实现的效果如下:通过后台下发token实现用户认证:
AuthMiddleware.go:
package middleware
import (
"ginEssential/common"
"ginEssential/model"
"github.com/gin-gonic/gin"
"net/http"
"strings"
)
/**
gin的中间件就是一个函数返回一个gin.HandlerFunc
*/
func AuthMiddleware() gin.HandlerFunc {
return func(ctx *gin.Context) {
//获取authorization header
tokenString := ctx.GetHeader("Authorization")
// validate token formate
if tokenString == "" || !strings.HasPrefix(tokenString,"Bearer ") {
ctx.JSON(http.StatusUnauthorized, gin.H{
"code": 401,
"msg": "权限不足",
})
ctx.Abort()
return
}
tokenString = tokenString[7:]
//解析token
token, claims, err := common.ParseToken(tokenString)
if err != nil || !token.Valid{
ctx.JSON(http.StatusUnauthorized, gin.H{
"code": 401,
"msg": "权限不足",
})
ctx.Abort()
return
}
//token通过了验证,获取token中userid
userId := claims.UserId
DB := common.GetDB()
var user model.User
DB.First(&user,userId)
//用户
if user.ID == 0 {//用户不存在
ctx.JSON(http.StatusUnauthorized, gin.H{
"code": 401,
"msg": "权限不足",
})
ctx.Abort()
return
}
//用户存在,将user信息写入上下文
ctx.Set("user", user)
ctx.Next()
}
}
jwt.go:
package common
import (
"ginEssential/model"
"github.com/dgrijalva/jwt-go"
"time"
)
/**
jwt : 实现用户认证和用户未知登录状态
*/
var jwtKey = []byte("a_secret_crect")
type Claims struct {
UserId uint
jwt.StandardClaims
}
/**
下发token
*/
func ReleaseToken(user model.User) (string, error) {
//token的过期时间
expireationTime := time.Now().Add(7*24*time.Hour)
claims := &Claims{
UserId: user.ID,
StandardClaims: jwt.StandardClaims{
ExpiresAt: expireationTime.Unix(),
IssuedAt:time.Now().Unix(),
Issuer: "yinlei",
Subject: "用户主题",
},
}
/**
token的组成部分:
//示例token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjUsImV4cCI6MTU4MzkzMTcwMSwiaWF0IjoxNTgzMzI2OTAxLCJpc3MiOiJ5aW5sZWkiLCJzdWIiOiLnlKjmiLfkuLvpopgifQ.BnO2oVHPshBMmqE7tlSac2VLjpk0Pb21e0zWX7Cym40
1.token使用的加密协议
2.playload:存储的是上面的具体信息
3.hash(加密协议+playload+key)的值 【可使用base64解密】
*/
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
tokenString, err := token.SignedString(jwtKey)
if err != nil {
return "", err
}
return tokenString, nil
}
/**
解析token
*/
func ParseToken(tokenString string) (*jwt.Token, *Claims, error){
claims := &Claims{}
token, err := jwt.ParseWithClaims(tokenString,claims, func(token *jwt.Token) (i interface{}, e error) {
return jwtKey, nil
})
return token, claims, err
}
这样就可以通过下发token并通过token配合jwt实现用户认证.
token的下发应该在登录里: