从4开始,在后端系统中增加用户注册和登录功能(下)

139 阅读2分钟

工具方法,用于生成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实现验证码功能,大家可以自行设计和补充哈。

除此之外,在系统的注册&登录功能背后,往往都会有系统的认证和授权,所以请大家耐心等待我的下一篇文章!