下载 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时,无权删除
登录获取token
再执行删除