内容简介:欢迎关注我的专栏( つ•̀ω•́)つ如何制作登录页面?如何从Mongo数据库中进行验证?上一篇文章
欢迎关注我的专栏( つ•̀ω•́)つ 【人工智能通识】
如何制作登录页面?如何从Mongo数据库中进行验证?
上一篇文章 软件技术-零基础-Golang用 MongoDB 验证用户信息
创建login.html
把我们原来的 login.html
文件复制一份重命名为 register.html
,因为登录和注册页面的代码很像,我们只要复制修改一下就可以重用了。
利用右下角的 Go Live
按钮启动实时预览,然后修改 login.html
页面。
- 首先,把原来简单的标题修改一下,增加跳转到
register.html
页面的链接:
<div class="row justify-content-center" style="margin-top:100px;margin-bottom:20px"> <h4>登录</h4> <div style="width:24px"></div> <a href="register.html" style="color:#CCC"><h4>注册</h4></a> </div>
效果如下:
- 然后删掉用户协议的旋钮部分,下面这个代码删掉。
<div class="form-check"> <input id='agree' onChange='checkBtn()' type="checkbox" class="form-check-input" id="exampleCheck1"> <label class="form-check-label" for="exampleCheck1"> <span>同意用户协议:</span> <a href='agreement.html'>点击阅读</a> </label> </div>
- 然后修改按钮的名称和动作名称,
regBtn
改为loginBtn
,sendRegPost
改为sendLoginPost
。
<button id='loginBtn' onClick="sendRegPost()" class="btn btn-pr...
- 修改
script
中的函数名称,sendRegPost
改为sendLoginPost
,并修改请求路径变为'/api/login'
,修改稿和是:
function sendLoginPost() { var data = { Email: $('#email').val(), Pw: $('#pw').val(), } $.post('/api/login', JSON.stringify(data), function (res) { alert(res.Msg); }, 'json') }
- 修改
script
中的checkBtn
方法,去掉对用户协议选项的检测。
//检查按钮是否可以被开启 function checkBtn() { var agree=$('#agree').is(':checked'); var mail = $('#email').val(); var pw = $('#pw').val(); if (pwRe.test(pw) && mailRe.test(mail)) { $('#regBtn').removeAttr('disabled') } else { $('#regBtn').attr('disabled', 'true') } }
创建login.go
同样我们复制 register.go
文件到路径 app/api/login/login.go
文件,然后修改它。
- 顶部第一行包名称改为
login
package login
- 然后修改
HandleFunc
函数内容,用FindOne
来读取用户的密码,和ds.Pw
进行对比,如果一致则返回成功,否则返回不匹配提示。
//HandleFunc 注册接口处理函数 func HandleFunc(w http.ResponseWriter, r *http.Request) { ds := ReqDS{} json.NewDecoder(r.Body).Decode(&ds) // //访问数据集 dbc := tools.MongoDBCLient.Database("myweb").Collection("user") //验证用户邮箱是否与用户名匹配 var u bson.M dbc.FindOne(context.TODO(), bson.M{"Email": ds.Email}).Decode(&u) if u["Pw"] == ds.Pw { util.WWrite(w, 0, "登录成功", u["_id"]) } else { util.WWrite(w, 1, "邮箱与用户名不匹配", nil) } return }
- 切换到
app.go
,把我们的新login.go
指定到对应的服务路径。
//注册登录相关 register.InitRun(tools) http.HandleFunc("/api/register", register.HandleFunc) login.InitRun(tools) http.HandleFunc("/api/login", login.HandleFunc)
然后重新 Run Code
,在浏览器中切换到 http://localhost:8088/page/login.html
,注意不是 Go Live
打开的页面。然后使用之前注册过的账号和密码尝试登陆,正常的话将显示成功。
改进tools.go使用方式
对于每个服务接口都要 register.InitRun(tools)
这看起来并不方便。能否像使用 util
那样使用 tool
?也就是只要 import "app/tool"
就可以直接用 tool.MongoDBCLient
,怎么做?
- 首先我们要在
tool.go
中创建MongoDBCLient
变量:
var MongoDBCLient *mongo.Client`
之前我们是依赖 InitRun
方法调用 initMongoDB()
来真的生成 MongoDBCLient
的,在 app.go
中我们还必须调用 tool.initRun()
才能呼叫成功。
实际上任何一个外部 go
文件被 import
的时候都会自动尝试运行 init()
函数,我们可以借用这个函数来自动生成 MongoDBCLient
,而不依赖手工呼叫:
//MongoDBCLient mongo数据库客户端,init中自动初始化 var MongoDBCLient *mongo.Client func init() { MongoDBCLient = initMongoDB() } func initMongoDB() *mongo.Client { ...
这样看起来简化不少。
- 在
app.go
文件中我们删除tool.InitRun()
代码,也去掉register.InitRun
和login.InitRun
代码。app.go
中main
函数内容:
func main() { //获取当前程序运行的目录 dir, _ := os.Getwd() webDir := path.Join(dir, "/web") //设置文件服务 http.Handle("/", http.FileServer(http.Dir(webDir))) //注册登录相关 http.HandleFunc("/api/register", register.HandleFunc) http.HandleFunc("/api/login", login.HandleFunc) //启动服务 fmt.Println("Server is running;CurrentDir is", dir) log.Fatal(http.ListenAndServe(":8088", nil)) }
- 简化
register.go
,先去掉InitRun
相关代码,以下代码删除。
var tools = uds.Tools{} //InitRun 初始化tools func InitRun(t uds.Tools) { tools = t }
然后把 dbc := tools.MongoDBCLient.Database...
一行改为 dbc := tool.MongoDBCLient.Database
,并在顶部添加导入:
import ( "app/util" "app/tool"
-
修改login.go。类似上面,一样去掉
InitRun
相关,增加import
,修改dbc:=tools.M...
为dcc:=tool.M...
。 -
去掉
udc.go
中的Tools
结构,因为我们不再需要它了。
最后运行,结合网页测试注册和登录功能。
虽然能够注册和登录,但是如果用假邮箱注册怎么办?用户忘记密码了怎么办?后续文章中我们继续扩展这些内容。
以下是主要文件的完整代码:
app.go
package main import ( "app/api/login" "app/api/register" "fmt" "log" "net/http" "os" "path" ) func main() { //获取当前程序运行的目录 dir, _ := os.Getwd() webDir := path.Join(dir, "/web") //设置文件服务 http.Handle("/", http.FileServer(http.Dir(webDir))) //API-注册登录相关 http.HandleFunc("/api/register", register.HandleFunc) http.HandleFunc("/api/login", login.HandleFunc) //启动服务 fmt.Println("Server is running;CurrentDir is", dir) log.Fatal(http.ListenAndServe(":8088", nil)) }
uds.go
package uds //Respons 定义统一的返回格式 type Respons struct { Code int Msg string Data interface{} }
tool.go
package tool import ( "context" "time" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" "go.mongodb.org/mongo-driver/mongo/readpref" ) //MongoDBCLient mongo数据库客户端,init中自动初始化 var MongoDBCLient *mongo.Client func init() { MongoDBCLient = initMongoDB() } //initMongoDB 初始化 工具 集 func initMongoDB() *mongo.Client { //连接服务 ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017")) defer cancel() if err != nil { panic(err) } //检测连接是否成功 ctx, cancel = context.WithTimeout(context.Background(), 2*time.Second) err = client.Ping(ctx, readpref.Primary()) defer cancel() if err != nil { panic(err) } return client }
util.go
package util import ( "app/uds" "encoding/json" "net/http" ) //WWrite 向用户返回信息,返回resp和一个错误信息 func WWrite(w http.ResponseWriter, code int, msg string, data interface{}) (uds.Respons, error) { resp := uds.Respons{Code: code, Msg: msg, Data: data} var err error dt, err1 := json.Marshal(resp) if err1 != nil { err = err1 } _, err2 := w.Write([]byte(string(dt))) if err2 != nil { err = err2 } return resp, err }
login.go
package login import ( "app/tool" "app/util" "context" "encoding/json" "net/http" "go.mongodb.org/mongo-driver/bson" ) //ReqDS 注册接口的请求数据格式 type ReqDS struct { Email string Pw string } //HandleFunc 注册接口处理函数 func HandleFunc(w http.ResponseWriter, r *http.Request) { ds := ReqDS{} json.NewDecoder(r.Body).Decode(&ds) // //访问数据集 dbc := tool.MongoDBCLient.Database("myweb").Collection("user") //验证用户邮箱是否与用户名匹配 var u bson.M dbc.FindOne(context.TODO(), bson.M{"Email": ds.Email}).Decode(&u) if u["Pw"] == ds.Pw { util.WWrite(w, 0, "登录成功", u["_id"]) } else { util.WWrite(w, 1, "邮箱与用户名不匹配", nil) } return }
register.go
package register import ( "app/tool" "app/util" "context" "encoding/json" "net/http" "regexp" "time" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" ) //ReqDS 注册接口的请求数据格式 type ReqDS struct { Email string Pw string } //HandleFunc 注册接口处理函数 func HandleFunc(w http.ResponseWriter, r *http.Request) { ds := ReqDS{} json.NewDecoder(r.Body).Decode(&ds) mailRe, _ := regexp.Compile(`^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$`) pwRe, _ := regexp.Compile(`^[0-9a-zA-Z_@]{6,18}$`) if !pwRe.MatchString(ds.Pw) { util.WWrite(w, 1, "密码格式错误。", nil) return } if !mailRe.MatchString(ds.Email) { util.WWrite(w, 1, "邮箱格式错误。", nil) return } //访问数据集 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) dbc := tool.MongoDBCLient.Database("myweb").Collection("user") defer cancel() //验证用户邮箱是否存在 count, err := dbc.CountDocuments(context.TODO(), bson.M{"Email": ds.Email}) if err != nil { util.WWrite(w, 1, "读取数据库失败。", nil) return } if count > 0 { util.WWrite(w, 1, "邮箱已存在。", nil) return } //写入数据库 res, err := dbc.InsertOne(ctx, bson.M{"Email": ds.Email, "Pw": ds.Pw}) if err != nil { util.WWrite(w, 1, "写入数据库失败。", nil) return } d := res.InsertedID.(primitive.ObjectID).Hex() util.WWrite(w, 0, "注册成功。", d) return }
register.html
<!doctype html> <html lang="zh-cmn-Hans"> <head> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <!-- Bootstrap CSS --> <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> <title>我的站点</title> </head> <body> <div class="container-fluid"> <div class="row justify-content-center" style="margin-top:100px;margin-bottom:20px"> <a href="login.html" style="color:#CCC"> <h4>登录</h4> </a> <div style="width:24px"></div> <h4>注册</h4> </div> <div class="row justify-content-center"> <div class="col-xs-10 col-sm-8 col-md-6 col-lg-4 col-xl-3"> <div class="form-group"> <label for="exampleInputEmail1">邮箱:</label> <input id='email' onkeyup="checkMail()" type="email" class="form-control" aria-describedby="emailHelp" placeholder="请输入正确格式的邮箱"> <small id='mailTip' style="display:none;">请输入正确邮箱格式</small> </div> <div class="form-group"> <label for="exampleInputPassword1">密码:</label> <input id='pw' onkeyup="checkPw()" type="password" class="form-control" placeholder="请输入6~18位密码"> <small id='pwTip' style="display:none">请输入6~18位数字字母或下划线</small> </div> <div class="form-check"> <input id='agree' onChange='checkBtn()' type="checkbox" class="form-check-input" id="exampleCheck1"> <label class="form-check-label" for="exampleCheck1"> <span>同意用户协议:</span> <a href='agreement.html'>点击阅读</a> </label> </div> <br> <button id='regBtn' onClick="sendRegPost()" class="btn btn-primary btn-block">注册</button> </div> </div> </div> <!-- Optional JavaScript --> <!-- jQuery first, then Popper.js, then Bootstrap JS --> <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/popper.js/1.12.9/umd/popper.min.js"></script> <script src="https://cdn.bootcss.com/bootstrap/4.0.0/js/bootstrap.min.js"></script> </body> <script type="text/javascript"> function sendRegPost() { var data = { Email: $('#email').val(), Pw: $('#pw').val(), } $.post('/api/register', JSON.stringify(data), function (res) { alert(res.Msg); }, 'json') } var mailRe = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; function checkMail() { var mail = $('#email').val(); if (mailRe.test(mail) == false) { $('#mailTip').css('display', 'block') $('#email').removeClass('is-valid') $('#email').addClass('is-invalid') } else { $('#mailTip').css('display', 'none') $('#email').removeClass('is-invalid') $('#email').addClass('is-valid') } checkBtn() } var pwRe = /^[0-9a-zA-Z_@]{6,18}$/ function checkPw() { var pw = $('#pw').val(); if (pwRe.test(pw) == false) { $('#pwTip').css('display', 'block') $('#pw').removeClass('is-valid') $('#pw').addClass('is-invalid') } else { $('#pwTip').css('display', 'none') $('#pw').removeClass('is-invalid') $('#pw').addClass('is-valid') } checkBtn() } //检查按钮是否可以被开启 function checkBtn() { var agree = $('#agree').is(':checked'); var mail = $('#email').val(); var pw = $('#pw').val(); if (pwRe.test(pw) && mailRe.test(mail)&& agree) { $('#regBtn').removeAttr('disabled') } else { $('#regBtn').attr('disabled', 'true') } } </script> </html>
login.html
<!doctype html> <html lang="zh-cmn-Hans"> <head> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <!-- Bootstrap CSS --> <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> <title>我的站点</title> </head> <body> <div class="container-fluid"> <div class="row justify-content-center" style="margin-top:100px;margin-bottom:20px"> <h4>登录</h4> <div style="width:24px"></div> <a href="register.html" style="color:#CCC"><h4>注册</h4></a> </div> <div class="row justify-content-center"> <div class="col-xs-10 col-sm-8 col-md-6 col-lg-4 col-xl-3"> <div class="form-group"> <label for="exampleInputEmail1">邮箱:</label> <input id='email' onkeyup="checkMail()" type="email" class="form-control" aria-describedby="emailHelp" placeholder="请输入正确格式的邮箱"> <small id='mailTip' style="display:none;">请输入正确邮箱格式</small> </div> <div class="form-group"> <label for="exampleInputPassword1">密码:</label> <input id='pw' onkeyup="checkPw()" type="password" class="form-control" placeholder="请输入6~18位密码"> <small id='pwTip' style="display:none">请输入6~18位数字字母或下划线</small> </div> <br> <button id='regBtn' onClick="sendLoginPost()" class="btn btn-primary btn-block">登录</button> </div> </div> </div> <!-- Optional JavaScript --> <!-- jQuery first, then Popper.js, then Bootstrap JS --> <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/popper.js/1.12.9/umd/popper.min.js"></script> <script src="https://cdn.bootcss.com/bootstrap/4.0.0/js/bootstrap.min.js"></script> </body> <script type="text/javascript"> function sendLoginPost() { var data = { Email: $('#email').val(), Pw: $('#pw').val(), } $.post('/api/login', JSON.stringify(data), function (res) { alert(res.Msg); }, 'json') } var mailRe = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; function checkMail() { var mail = $('#email').val(); if (mailRe.test(mail) == false) { $('#mailTip').css('display', 'block') $('#email').removeClass('is-valid') $('#email').addClass('is-invalid') } else { $('#mailTip').css('display', 'none') $('#email').removeClass('is-invalid') $('#email').addClass('is-valid') } checkBtn() } var pwRe = /^[0-9a-zA-Z_@]{6,18}$/ function checkPw() { var pw = $('#pw').val(); if (pwRe.test(pw) == false) { $('#pwTip').css('display', 'block') $('#pw').removeClass('is-valid') $('#pw').addClass('is-invalid') } else { $('#pwTip').css('display', 'none') $('#pw').removeClass('is-invalid') $('#pw').addClass('is-valid') } checkBtn() } //检查按钮是否可以被开启 function checkBtn() { var agree=$('#agree').is(':checked'); var mail = $('#email').val(); var pw = $('#pw').val(); if (pwRe.test(pw) && mailRe.test(mail)) { $('#regBtn').removeAttr('disabled') } else { $('#regBtn').attr('disabled', 'true') } } </script> </html>
欢迎关注我的专栏( つ•̀ω•́)つ 【人工智能通识】
每个人的智能新时代
如果您发现文章错误,请不吝留言指正;
如果您觉得有用,请点喜欢;
如果您觉得很有用,欢迎转载~
END
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 软件技术-零基础编写响应式登录页面
- 热议GIS软件技术四大升维,2018 GIS 软件技术大会在京举办
- Anatova勒索软件技术分析
- 软件技术职业选择之道.pdf
- ABCDE时代,GIS软件技术再升维
- GIS软件技术实现升维 带来全新应用价值
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
王牌创业者:风口游戏
澈言 / 百花洲文艺出版社 / 2018-2 / 48.00
《王牌创业者:风口游戏》是一部围绕互联网创业展开的商战小说:故事的主人公莫飞是“毕业即创业”的当代年轻创业者的典型代表,他大学在校时就凭借创业项目拿到了天使融资,创业几年后,当产品估值越做越大时,他却忽然遭遇创业伙伴及投资人的联手陷害,失去了自己一手建立的公司。 此时, 莫飞的女友林姿参加了一场声势浩大的创业比赛,并一举夺魁,直进决赛。可在决赛中,突如其来的一场新闻事件让她名誉扫地。最终,为......一起来看看 《王牌创业者:风口游戏》 这本书的介绍吧!