这两天比较忙。现在继续搞。jwt验证登录
首先是 引入 jwt
go get -u github.com/dgrijalva/jwt-go
然后在gin-demo/common/jwt.go中
package common
import (
"errors"
"github.com/dgrijalva/jwt-go"
"time"
)
type Myclaims struct {
Username string `json:"username"`
jwt.StandardClaims
}
var Secret = []byte("secret")
const TokenExpireDuration = time.Hour * 24
// GenToken 生成Token
func GenToken(username string)(string,error){
c := Myclaims{
Username: username,
StandardClaims: jwt.StandardClaims{
ExpiresAt: time.Now().Add(TokenExpireDuration).Unix(),
Issuer: "gin-demo",
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256,c)
return token.SignedString(Secret)
}
// ParseToken 解析token
func ParseToken(tokenString string)(*Myclaims,error){
token,err := jwt.ParseWithClaims(tokenString,&Myclaims{}, func(token *jwt.Token) (interface{}, error) {
return Secret,nil
})
if err != nil {
return nil, err
}
if claims, ok := token.Claims.(*Myclaims); ok && token.Valid {
return claims, nil
}
return nil, errors.New("invalid token")
}
然后在登录的时候生成token
func Login(c *gin.Context){
db := common.GetDB()
var reqUser model.User
c.Bind(&reqUser)
mobile := reqUser.Mobile
password := reqUser.Password
var user model.User
//查询数据
db.Where("mobile = ?", mobile).First(&user)
if user.ID == 0 {
response.Response(c,http.StatusUnprocessableEntity,422,"用户不存在",gin.H{})
return
}
//密码的对比
if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)); err != nil {
response.Response(c,http.StatusUnprocessableEntity,422,"用户不存在",gin.H{})
return
}
//登录成功前先生成token
token, err := common.GenToken(user.Username)
if err != nil {
response.Response(c,http.StatusUnprocessableEntity,422,"生成token失败",gin.H{})
return
}
response.Success(c,gin.H{"user":user,"token":token},"登录成功")
}
登录成功后,在浏览器存储gin-demo/template/user/Login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>登录页</title>
<link rel="stylesheet" href="../../static/css/bootstrap.min.css">
<script src="../../static/js/jquery.min.js"></script>
<script src="../../static/js/bootstrap.min.js"></script>
</head>
<style>
.login-block {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
</style>
<body style="background:url(../../static/img/background.jpg) no-repeat center; background-position: center 0; background-size: cover; margin: 0px;">
<div>
<!-- <form class="form-group">-->
<div class="col-md-4 col-lg-4 col-lg-offset-4 col-md-offset-4 login-block"
style="background-color: white; opacity: 0.8; padding: 50px; border-radius: 15px">
<h3 style="text-align: center;padding-bottom:20px;font-family:Helvetica Neue, Helvetica, Arial, sans-serif;font-size: 40px">
用户登录</h3>
<div class="form-group input-group input-group-lg">
<span class="input-group-addon">手机号码</span>
<input type="text" id="mobile" name="Mobile" class="form-control" placeholder="手机号码"
value="{{.reqUser.Mobile}}">
</div>
<div class="form-group input-group input-group-lg">
<span class="input-group-addon">密码 </span>
<input type="password" id="password" name="Password" class="form-control" placeholder="密码"
value="{{.reqUser.Password}}">
</div>
<div class="form-group center-block">
<button class="btn btn-success center-block" style="width: 80px;height: 40px;font-size: 20px"
id="login-submit">登 录
</button>
<a href="/user/register">没有账户?点击注册</a>
</div>
</div>
<!-- </form>-->
</div>
</body>
<script>
$(document).ready(function () {
$("#login-submit").click(function () {
let mobile = $("#mobile").val();
let password = $("#password").val();
$.ajax({
type: "post",
url: "/user/login",
data: {"Mobile": mobile, "Password": password},
dataType: "json",
async: true,
success: function (res) {
if (res.code == 200) {
//浏览器存储token
window.sessionStorage.setItem('token', res.data.token);
window.location.href = "/cate/list";
}
}
})
});
});
</script>
</html>
其他页面可以加上如:gin-demo/template/tag/TagList.html
{{template "header.html" .}}
{{template "nav.html" .}}
<!-- 左侧导航和正文内容的分隔线 -->
<div class="splitter"></div>
<!-- 正文内容部分 -->
<div class="pageContent">
<div class="container-fluid">
<h1 class="mt-4" style="font-size: 30px;text-align: center">标签列表</h1>
<div class="card mb-4">
<div class="card-header" style="height: 30px">
<a class=" btn navbar-brand btn-success" href="/tag/add">添加标签</a>
</div>
<div class="card-body" style="padding-top: 20px;margin-top: 5px">
<table class="table table-bordered table-hover" id="datatablesSimple">
<thead>
<tr>
<th>ID</th>
<th>分类名</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{{range .tagList}}
<tr>
<td>{{.ID}}</td>
<td>{{.TagName}}</td>
<td><a href="/tag/edit?id={{.ID}}">编辑</a>|<a href="/tag/delete?id={{.ID}}">删除</a></td>
</tr>
{{end}}
</tbody>
</table>
</div>
</div>
</div>
</div>
<script>
//判断token是否存在,不存在就到登录页
$(document).ready(function (){
token = sessionStorage.getItem('token');
if(token === null){
window.location.href="/user/login";
}
})
</script>
{{template "footer.html" .}}
然后在gin-demo/middleware/jwt.go创建中间件:
package middleware
import (
"fmt"
"gin-demo/common"
"gin-demo/response"
"github.com/gin-gonic/gin"
"net/http"
)
// JwtAuthMiddleware 登录验证中间件
func JwtAuthMiddleware() func(c *gin.Context){
return func(c *gin.Context) {
authHeader :=c.Request.Header.Get("Authorization")
fmt.Println(authHeader)
if authHeader == ""{
response.Response(c,http.StatusUnauthorized,401,"请求的auth为空",gin.H{})
c.Abort()
return
}
reqToken,err := common.ParseToken(authHeader)
if err != nil {
response.Response(c,http.StatusUnauthorized,401,"token验证失败",gin.H{})
c.Abort()
return
}
c.Set("username",reqToken.Username)
c.Next()
}
}
在路由中加入中间件验证,这里就加了两个来验证效果
package router
import (
"gin-demo/controller"
"gin-demo/middleware"
"github.com/gin-gonic/gin"
)
func InitRouter(r *gin.Engine) *gin.Engine{
r.LoadHTMLGlob("template/**/*")
//加载静态资源
r.Static("/static", "./static")
//首页页面
r.GET("/index", controller.IndexPage)
//注册
r.POST("/user/register", controller.Register)
r.GET("/user/register", controller.RegisterPage)
//登录
r.POST("/user/login", controller.Login)
r.GET("/user/login", controller.LoginPage)
//分类页面
r.GET("/cate/list", controller.CategoryListPage)
r.GET("/cate/add", controller.CategoryAddPage)
r.GET("/cate/edit", controller.CategoryEditPage)
r.GET("/cate/delete", controller.DeleteCate)
r.POST("/cate/add",middleware.JwtAuthMiddleware(),controller.AddCate)
r.POST("/cate/edit", controller.EditCate)
//标签页面
r.GET("/tag/list", controller.TagListPage)
r.GET("/tag/add", controller.TagAddPage)
r.GET("/tag/edit", controller.TagEditPage)
r.GET("/tag/delete", controller.DeleteTag)
r.POST("/tag/add",middleware.JwtAuthMiddleware(), controller.AddTag)
r.POST("/tag/edit", controller.EditTag)
return r
}
前端代码:gin-demo/template/tag/TagAddhtml
{{template "header.html" .}}
{{template "nav.html" .}}
<!-- 左侧导航和正文内容的分隔线 -->
<div class="splitter"></div>
<!-- 正文内容部分 -->
<div class="pageContent">
<div>
<!-- {{if .tagRow.ID}}-->
<!--<!– <form action="/tag/edit" method="post">–>-->
<!-- {{else}}-->
<!--<!– <form action="/tag/add" method="post">–>-->
<!-- {{end}}-->
<div class="col-md-4 col-lg-4 col-lg-offset-4 col-md-offset-4 login-block"
style="background-color: white; opacity: 0.8; padding: 50px; border-radius: 15px">
<h3 style="text-align: center;padding-bottom:20px;font-family:Helvetica Neue, Helvetica, Arial, sans-serif;font-size: 40px">
标签名称添加</h3>
<div class="form-group input-group input-group-lg">
<span class="input-group-addon" id="CateName">标签名称</span>
<input type="hidden" name="ID" class="form-control" id="id" value="{{.tagRow.ID}}">
<input type="text" name="TagName" class="form-control" id="tag_name" placeholder="标签名称"
value="{{.tagRow.TagName}}">
</div>
<div class="form-group center-block">
<button class="btn btn-success center-block" style="width: 80px;height: 40px;font-size: 20px"
id="tag_add">保存
</button>
</div>
</div>
<!-- </form>-->
</div>
</div>
</div>
</div>
<script>
$(document).ready(function () {
token = window.sessionStorage.getItem('token');
if (token === null) {
window.location.href = "/user/login";
}
$("#tag_add").click(function () {
var id = $("#id").val();
var tagName = $("#tag_name").val();
token = window.sessionStorage.getItem('token');
$.ajax({
type: "POST",
dataType: "json",
url: id === "" ? "/tag/add" : "/tag/edit",
data: {'token': token, 'TagName': tagName, 'ID': id},
beforeSend: function (xhr) {
token = window.sessionStorage.getItem('token');
xhr.setRequestHeader("Authorization", token);
},
success: function (result, status, xhr) {
if (result.code === 200) {
window.location.href = "/tag/list";
}
}
})
})
})
</script>
{{template "footer.html" .}}
可以发现没有登录,不允许操作。
前端写得真难看的我 哈哈哈哈