包
"github.com/dgrijalva/jwt-go"
1.jwt配置
//定义负载
type Claims struct {
model.User //这是任意的
jwt.StandardClaims
}
//过期时间
const TokenExpireDuration = time.Second * 120
//设置密码
var secret = []byte("secret")
//生成token
func GetToken(user model.User) (string, error) {
c := Claims{
User: user,
StandardClaims: jwt.StandardClaims{
ExpiresAt: time.Now().Add(TokenExpireDuration).Unix(), //过期时间
Issuer: "wrl", //签发人
},
}
// 使用指定的签名方法创建签名对象
tokenObject := jwt.NewWithClaims(jwt.SigningMethodHS256, c)
// 使用指定的secret签名并获得完整的编码后的字符串token
tokenEncode, err := tokenObject.SignedString(secret)
return tokenEncode, err
}
//解析token
func VerifyToken(token string) (*Claims, error) {
tokenObj, err := jwt.ParseWithClaims(token, &Claims{}, func(token *jwt.Token) (i interface{}, e error) {
return secret, nil
})
if claims, ok := tokenObj.Claims.(*Claims); ok && tokenObj.Valid {
fmt.Printf("%v %v", claims.UserName, claims.StandardClaims.ExpiresAt)
return tokenObj.Claims.(*Claims), err
}
return nil, err
}
2.过滤器
import (
"CasbinProject/config"
"CasbinProject/service"
"fmt"
"github.com/gin-gonic/gin"
"net/http"
)
func JWTAuthMiddleware() func(c *gin.Context) {
return func(c *gin.Context) {
str := c.Request.RequestURI
fmt.Println(str)
// 客户端携带Token有三种方式 1.放在请求头 2.放在请求体 3.放在URI
// 这里假设Token放在Header的Authorization中,并使用Bearer开头
// 这里的具体实现方式要依据你的实际业务情况决定
authHeader := c.Request.Header.Get("Authorization")
if authHeader == "" {
c.JSON(http.StatusOK, gin.H{
"code": 2003,
"msg": "请求头中auth为空",
})
c.Abort()
return
}
//parts := strings.SplitN(authHeader, " ", 2)
//if !(len(parts) == 2 && parts[0] == "Bearer") {
// c.JSON(http.StatusOK, gin.H{
// "code": 2004,
// "msg": "请求头中auth格式有误",
// })
// c.Abort()
// return
//}
// parts[1]是获取到的tokenString,我们使用之前定义好的解析JWT的函数来解析它
mc, err := config.VerifyToken(authHeader)
if err != nil {
c.JSON(http.StatusOK, gin.H{
"code": 2005,
"msg": "无效的Token",
})
config.Remove(mc.UUID)
c.Abort()
return
}
//token, _ := config.Get(mc.UUID)
//if token != authHeader {
// c.JSON(http.StatusOK, gin.H{
// "code": 2005,
// "msg": "令牌错误",
// })
// c.Abort()
// return
//}
ok := service.AuthorityCheck(mc.UserName, c.Request.RequestURI, "visit")
if !ok {
c.JSON(http.StatusForbidden, gin.H{
"msg": "无权访问",
})
c.Abort()
return
}
// 将当前请求的username信息保存到请求的上下文c上
c.Set("username", mc.UserName)
c.Next() // 后续的处理函数可以用过c.Get("username")来获取当前请求的用户信息
}
}