工具方法,用于生成token和MD5加密:
package utils
import (
"bytes"
"crypto/md5"
"encoding/gob"
"encoding/hex"
"math/rand"
"strings"
"time"
)
func GetMd5Str(str string) string {
md5 := md5.New()
var buf bytes.Buffer
gob.NewEncoder(&buf).Encode(str)
md5.Write(buf.Bytes())
return hex.EncodeToString(md5.Sum(nil))
}
func GetTokenStr() string {
char := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
charArr := strings.Split(char, "")
c := len(charArr)
ran := rand.New(rand.NewSource(time.Now().Unix()))
var str string = ""
for i := 1; i <= 18; i++ {
str = str + charArr[ran.Intn(c)]
}
return str
}
工具方法:
package utils
import (
"time"
)
// NowTimeStr return 2022-01-21 12:21:31
func NowTimeStr() string {
return time.Unix(time.Now().Unix(), 0).Format("2006-01-02 15:04:05")
}
// NowTimeStamp return 1657255820
func NowTimeStamp() int64 {
return time.Now().Unix()
}
// TimeStamp2NowTimeStr 1657255820 -> 2022-01-21 12:21:31
func TimeStamp2NowTimeStr(stamp int64) string {
format := time.Unix(stamp, 0).Format("2006-01-02 15:04:05")
return format
}
// NowTimeStr2TimeStamp 2022-01-21 12:21:31 -> 1657255820
func NowTimeStr2TimeStamp(str string) int64 {
var LOC, _ = time.LoadLocation("Asia/Shanghai")
tim, _ := time.ParseInLocation("2006-01-02 15:04:05", str, LOC)
return tim.Unix()
}
controller层:
package controller
import (
"count_num/pkg/dao/impl"
"count_num/pkg/model"
"count_num/pkg/utils"
"count_num/pkg/web/auth"
"encoding/json"
"github.com/gin-gonic/gin"
"io/ioutil"
)
type UserControllerImpl struct {
dao *impl.UserDaoImpl
}
type UserController interface {
CreateUser(c *gin.Context)
FindUserByLoginNameAndPwd(c *gin.Context)
Register(c *gin.Context)
}
func NewUserController() *UserControllerImpl {
return &UserControllerImpl{dao: impl.NewUserDaoImpl()}
}
func (impl UserControllerImpl) CreateUser(c *gin.Context) {
body := c.Request.Body
bytes, err := ioutil.ReadAll(body)
user := model.User{}
json.Unmarshal(bytes, &user)
if err != nil {
panic(err)
}
res := impl.dao.CreateUser(c, user)
c.JSON(200, map[string]interface{}{"code": 0, "msg": "", "count": 0, "data": res})
}
func (impl UserControllerImpl) FindUserByLoginNameAndPwd(c *gin.Context) {
body := c.Request.Body
bytes, err := ioutil.ReadAll(body)
user := model.User{}
json.Unmarshal(bytes, &user)
if err != nil {
panic(err)
}
userByLoginName := impl.dao.GetUserByLoginName(c, user.LoginName)
//密码通过
if userByLoginName.Pwd == utils.GetMd5Str(user.Pwd) {
setToken := auth.SetToken(c, utils.GetTokenStr(), user)
c.JSON(200, map[string]interface{}{"code": 0, "msg": setToken, "count": 0, "data": utils.GetTokenStr()})
} else {
if userByLoginName.Id == 0 {
c.JSON(200, map[string]interface{}{"code": 0, "msg": "账号不存在", "count": 0, "data": "-1"})
} else {
c.JSON(200, map[string]interface{}{"code": 0, "msg": "密码错误", "count": 0, "data": "-1"})
}
}
}
func (impl UserControllerImpl) Register(c *gin.Context) {
body := c.Request.Body
bytes, err := ioutil.ReadAll(body)
user := model.User{}
json.Unmarshal(bytes, &user)
if err != nil {
panic(err)
}
user.Role = 1
res := impl.dao.CreateUser(c, user)
c.JSON(200, map[string]interface{}{"code": 0, "msg": "", "count": 0, "data": res})
}
router增加URL:
......
userInfo := r.Group("/user")
{
userInfo.POST("/save", controller.NewUserController().CreateUser)
userInfo.POST("/login", controller.NewUserController().FindUserByLoginNameAndPwd)
userInfo.POST("/register", controller.NewUserController().Register)
}
......
前端代码:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>登录/注册</title>
<link rel="stylesheet" href="./layui/css/layui.css">
<style>
#form {
width: 30%;
margin-left: 35%;
margin-top: 200px;
padding: 30px;
border: 3px solid #c5c5b0;
border-radius: 20px;
}
#form2 {
width: 30%;
margin-left: 35%;
margin-top: 200px;
padding: 30px;
border: 3px solid #c5c5b0;
border-radius: 20px;
}
.hidden {
display: none;
}
.show {
display: block;
}
</style>
</head>
<body>
<form class="layui-form" id="form">
<h3 style="font-size: 20px;text-align: center;margin-bottom: 30px;">登录</h3>
<div class="layui-form-item">
<label class="layui-form-label">账号</label>
<div class="layui-input-inline">
<input type="text" id="loginName" placeholder="请输入账号" autocomplete="off"
class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">密码</label>
<div class="layui-input-inline">
<input type="password" id="loginPwd" placeholder="请输入密码" autocomplete="off"
class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" type="button" onclick="login()">立即提交</button>
<button type="button" onclick="toRegister()" class="layui-btn layui-btn-primary">注册</button>
</div>
</div>
</form>
<form class="layui-form hidden" id="form2">
<h3 style="font-size: 20px;text-align: center;margin-bottom: 30px;">注册</h3>
<div class="layui-form-item">
<label class="layui-form-label">昵称</label>
<div class="layui-input-inline">
<input type="text" id="regName" placeholder="请输入昵称" autocomplete="off"
class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">账号</label>
<div class="layui-input-inline">
<input type="text" id="regLoginName" placeholder="请输入账号" autocomplete="off"
class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">密码</label>
<div class="layui-input-inline">
<input type="password" id="regPwd" placeholder="请输入密码" autocomplete="off"
class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">确认密码</label>
<div class="layui-input-inline">
<input type="password" id="regPwd2" placeholder="请再次输入密码"
autocomplete="off"
class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">身份</label>
<div class="layui-input-block">
<input type="radio" id="role" value="user" title="用户" checked>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" type="button" onclick="register()">立即提交</button>
<button type="button" onclick="toLogin()" class="layui-btn layui-btn-primary">登录</button>
</div>
</div>
</form>
</body>
<script src="./layui/layui.js"></script>
<script src="./layui/jquery.min.js"></script>
<script>
var base_url = 'http://localhost:9888'
function login() {
var loginName = $("#loginName").val()
var loginPwd = $("#loginPwd").val()
var data = {
'login_name': loginName,
'pwd': loginPwd
}
$.ajax({
url: base_url + "/user/login",
type: "POST",
data: JSON.stringify(data),
success: function (res) {
if (res.data.length >= 10) {
localStorage.setItem("token", res.data)
return;
}
alert(res.msg)
return
},
error: function (err) {
alert(err)
return
}
})
}
function register() {
var regName = $("#regName").val()
var regLoginName = $("#regLoginName").val()
var regPwd = $("#regPwd").val()
var regPwd2 = $("#regPwd2").val()
if (regPwd != regPwd2) {
alert("密码不一致鸭")
return
}
var data = {
'name': regName,
'login_name': regLoginName,
'pwd': regPwd
}
$.ajax({
url: base_url + "/user/register",
type: "POST",
data: JSON.stringify(data),
success: function (res) {
if (res.data) {
alert("注册成功")
} else {
alert("注册失败")
}
},
error: function (err) {
console.log(err)
}
})
}
function toLogin() {
$("#form2").addClass("hidden")
$("#form").removeClass("hidden")
}
function toRegister() {
$("#form").addClass("hidden")
$("#form2").removeClass("hidden")
}
</script>
</html>
3 小结
用户的登录和注册功能在一般情况下会使用到验证码,所以这里准备了一篇文章:一文搞懂Go整合captcha实现验证码功能,大家可以自行设计和补充哈。
除此之外,在系统的注册&登录功能背后,往往都会有系统的认证和授权,所以请大家耐心等待我的下一篇文章!