核心代码如下:
package main
import (
"github.com/dgrijalva/jwt-go" //快速生成token
"temp/Gin/gin-go/model"
"time"
)
var jwtKey = []byte("a_secret_key") //证书签名秘钥(该秘钥非常重要,如果client端有该秘钥,就可以签发证书了)
type Claims struct {
UserId uint
jwt.StandardClaims
}
//分发证书
func ReleaseToken(user model.User) (string, error) {
expirationTime := time.Now().Add(7 * 24 * time.Hour) //截止时间:从当前时刻算起,7天
claims := &Claims{
UserId: user.ID,
StandardClaims: jwt.StandardClaims{
ExpiresAt: expirationTime.Unix(), //过期时间
IssuedAt: time.Now().Unix(), //发布时间
Issuer: "jiangzhou", //发布者
Subject: "user token", //主题
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) //生成token
tokenString, err := token.SignedString(jwtKey) //签名
if err != nil {
return "", err
}
return tokenString, nil
}
//解析证书
func ParseToken(tokenString string) (*jwt.Token, *Claims, error){
claims := &Claims{}
token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (i interface{}, err error) {
return jwtKey, nil
})
return token, claims, err
}
token验证:
//token认证中间件(权限控制)
func AuthMiddleware() gin.HandlerFunc {
return func(ctx *gin.Context) {
auth:="jiangzhou"
// 获取authorization header
tokenString := ctx.GetHeader("Authorization") //postman测试:在Headers中添加: key:Authorization;value:jiangzhou:xxx(token值)
//fmt.Println(tokenString)
//fmt.Println(strings.HasPrefix(tokenString,auth+""))
// 无效的token
//if tokenString == "" || !strings.HasPrefix(tokenString, "Bearer ") { //验证token的前缀为:
if tokenString == "" || !strings.HasPrefix(tokenString, auth+":") { //验证token的前缀为:
ctx.JSON(http.StatusUnauthorized, gin.H{"code": 401, "msg": "权限不足"})
ctx.Abort()
return
}
index:=strings.Index(tokenString,auth+":") //找到token前缀对应的位置
tokenString = tokenString[index+len(auth)+1:] //截取真实的token(开始位置为:索引开始的位置+关键字符的长度+1(:的长度为1))
//fmt.Println("截取之后的数据:",tokenString)
token, claims, err := common.ParseToken(tokenString)
if err != nil || !token.Valid { //解析错误或者过期等
ctx.JSON(http.StatusUnauthorized, gin.H{"code": 401, "msg": "权限不足"})
ctx.Abort()
return
}
// 验证通过后获取claim 中的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) //将key-value值存储到context中
// before request
ctx.Next()//执行内部的pending handlers
}
}
采用的web框架为Gin,通过中间件来实现验证。在以上代码中,签名采用的是Hash256。