6、ginBlog 使用 JWT 进行登录校验

下载 jwt-go 的依赖包

go get -u github.com/dgrijalva/jwt-go

config 目录下config.ini添加

[server]
# jwtKey 随机输入的
JwtKey = rwqrq124124weq

在utils目录下的setting.go

JwtKey	 string

	JwtKey = file.Section("server").Key("JwtKey").MustString("rwqrq124124weq")


在middleware下的util目录新建jwt.go
╰─➤  cat middleware/jwt.go 
package middleware

import (
        "ginBlog/utils"
        "ginBlog/utils/errmsg"
        jwt "github.com/dgrijalva/jwt-go"
        "github.com/gin-gonic/gin"
        "net/http"
        "strings"
        "time"
)

var JwtKey = []byte(utils.JwtKey)

type MyClaims struct {
        Username string `json:"username"`
        jwt.StandardClaims
}

// 生成token
func SetToken(username string) (string, int) {
        //      token 有效期
        expireTime := time.Now().Add(10 * time.Hour)
        // MyClaims 赋值
        SetClaims := MyClaims{
                username,
                jwt.StandardClaims{
                        ExpiresAt: expireTime.Unix(),
                        Issuer:    "ginBlog",
                },
        }

        // 生成token
        reqClaim := jwt.NewWithClaims(jwt.SigningMethodHS256, SetClaims)
        token, err := reqClaim.SignedString(JwtKey)
        if err != nil {
                return "", errmsg.ERROR
        }
        return token, errmsg.SUCCESS
}

// 验证 token
func CheckToken(token string) (*MyClaims, int) {
        setToken, err := jwt.ParseWithClaims(token, &MyClaims{}, func(token *jwt.Token) (i interface{}, e error) {
                return JwtKey, nil
        })

        if err != nil {
                if ve, ok := err.(*jwt.ValidationError); ok { //官方写法照抄就行
                        if ve.Errors&jwt.ValidationErrorMalformed != 0 {
                                return nil, errmsg.ERROR_TOKEN_WRONG
                        } else if ve.Errors&(jwt.ValidationErrorExpired|jwt.ValidationErrorNotValidYet) != 0 {
                                return nil, errmsg.ERROR_TOKEN_RUNTIME
                        } else {
                                return nil, errmsg.ERROR_TOKEN_WRONG
                        }
                }
        }
        if setToken != nil {
                if key, ok := setToken.Claims.(*MyClaims); ok && setToken.Valid {
                        return key, errmsg.SUCCESS
                } else {
                        return nil, errmsg.ERROR_TOKEN_WRONG
                }
        }
        return nil, errmsg.ERROR_TOKEN_WRONG
}

// jwt 中间件
func JwtToken() gin.HandlerFunc {
        return func(c *gin.Context) {
                var code int
                tokenHeader := c.Request.Header.Get("Authorization")
                if tokenHeader == "" {
                        code = errmsg.ERROR_TOKEN_EXIST
                        c.JSON(http.StatusOK, gin.H{
                                "code":    code,
                                "message": errmsg.GetErrMsg(code),
                        })
                        c.Abort()
                        return
                }

                checkToken := strings.Split(tokenHeader, " ")
                if len(checkToken) == 0 {
                        code = errmsg.ERROR_TOKEN_WRONG
                        c.JSON(http.StatusOK, gin.H{
                                "code":    code,
                                "message": errmsg.GetErrMsg(code),
                        })
                        c.Abort()
                        return
                }

                if len(checkToken) != 2 && checkToken[0] != "Bearer" {
                        code = errmsg.ERROR_TOKEN_WRONG
                        c.JSON(http.StatusOK, gin.H{
                                "code":    code,
                                "message": errmsg.GetErrMsg(code),
                        })
                        c.Abort()
                        return
                }

                key, tCode := CheckToken(checkToken[1])
                if tCode != errmsg.SUCCESS {
                        code = tCode
                        c.JSON(http.StatusOK, gin.H{
                                "code":    code,
                                "message": errmsg.GetErrMsg(code),
                        })
                        c.Abort()
                        return
                }

                if time.Now().Unix() > key.ExpiresAt {
                        code = errmsg.ERROR_TOKEN_RUNTIME
                        c.Abort()
                }

                c.Set("username", key)
                c.Next()
        }
}

在 model目录下User.go文件里面增加方法

╰─➤  cat model/User.go
// 登录验证
func CheckLogin(username, password string) int {
        var user User
        db.Where("username = ?", username).First(&user)

        if user.ID == 0 {
                return errmsg.ERROR_USER_NOT_EXIST
        }

        if ScryptPw(password) != user.Password {
                return errmsg.ERROR_PASSWORD_WORNG
        }

        if user.Role != 1 {
                return errmsg.ERROR_USER_NOT_RIGHT
        }

        return errmsg.SUCCESS
}

在api/v1目录下的login.go增加路由

╰─➤  cat api/v1/login.go 
package v1

import (
        "ginBlog/middleware"
        "ginBlog/model"
        "ginBlog/utils/errmsg"
        "github.com/gin-gonic/gin"
        "net/http"
)

// 登录验证
func Login(c *gin.Context) {
        var data model.User
        c.ShouldBindJSON(&data)

        var token string
        var code int
        code = model.CheckLogin(data.Username, data.Password)

        if code == errmsg.SUCCESS {
                token, code = middleware.SetToken(data.Username)
        }

        c.JSON(http.StatusOK, gin.H{
                "status":  code,
                "token":   token,
                "message": errmsg.GetErrMsg(code),
        })
}

jwt接入gin路由

╰─➤  cat routers/router.go 
package routers

import (
        v1 "ginBlog/api/v1"
        "ginBlog/middleware"
        "ginBlog/utils"
        "github.com/gin-gonic/gin"
)

func InitRouter() {
        gin.SetMode(utils.AppMode)
        r := gin.Default()

        // 使用jwt 验证
        authV1 := r.Group("api/v1")
        authV1.Use(middleware.JwtToken())
        {
                // 用户模块的路由接口
                authV1.PUT("user/:id", v1.EditUser)
                authV1.DELETE("user/:id", v1.DeleteUser)

                //      分类 的路由接口
                authV1.POST("cate/add", v1.AddCate)
                authV1.PUT("cate/:id", v1.EditCate)
                authV1.DELETE("cate/:id", v1.DeleteCate)

                // 文章的路由接口
                authV1.POST("article/add", v1.AddArticle)
                authV1.PUT("article/:id", v1.EditArticle)
                authV1.DELETE("article/:id", v1.DeleteArticle)
        }

        // 直接访问
        routerV1 := r.Group("api/v1")
        {
                routerV1.POST("user/add", v1.AddUser)
                routerV1.GET("users", v1.GetUsers)

                routerV1.GET("cates", v1.GetCates)

                routerV1.GET("article/list/:id", v1.GetArtByCate)
                routerV1.GET("article/info/:id", v1.GetArtInfo)
                routerV1.GET("articles", v1.GetArticles)
                routerV1.POST("login", v1.Login)
        }

        r.Run(utils.HttpPort)
}

jwt验证

不适用token时,无权删除

image

登录获取token

image

再执行删除

image

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值