go实现jwt-demo
1.JSON web token(jwt) 是自己携带一些信息,jwt现在越来越流行原因如下:
·1.jwt是无状态,因此不需要任何数据库来存储
2.jwt签名是安全
3.jwt可以设置有效时间,可以减少黑客攻击
jwt官网介绍
2.用户登录之后生成token
func Login(c *gin.Context) {
var user models.User
if err := c.ShouldBindJSON(&user); err != nil {
c.JSON(http.StatusUnprocessableEntity, "invalid json provided")
return
}
token, err := authorization.CreateToken(user.ID)
if err != nil {
c.JSON(http.StatusInternalServerError, err.Error())
return
}
c.JSON(http.StatusOK, token)
}
//通过用户信息获取token
func CreateToken(userId int64) (string, error) {
var err error
os.Setenv("ACCESS_SECRET", "KKKK")
atCliams := jwt.MapClaims{}
atCliams["authorized"] = true
atCliams["userId"] = userId
atCliams["exp"] = time.Now().Add(time.Minute * 15).Unix()
at := jwt.NewWithClaims(jwt.SigningMethodHS256, atCliams)
token, err := at.SignedString([]byte(os.Getenv("ACCESS_SECRET")))
if err != nil {
return "", err
}
return token, err
}
3.校验生成token
用户操作需要校验token
func CreateTodo(c *gin.Context) {
var td *models.Todo
if err := c.ShouldBindJSON(&td); err != nil {
c.JSON(http.StatusUnprocessableEntity, "invalid json")
return
}
//从token中获取用户信息
tokenAuth, err := authorization.ExtractTokenMetaData(c.Request)
if err != nil {
c.JSON(http.StatusUnprocessableEntity, "unauthorized")
return
}
userId, err := dao.FetchAuth(tokenAuth)
if err != nil {
c.JSON(http.StatusUnprocessableEntity, "unauthorized")
return
}
td.UserId = userId
c.JSON(http.StatusCreated, td)
}
//获取jwt原信息
func ExtractTokenMetaData(r *http.Request) (*models.AccessDetails, error) {
token, err := VerifyToken(r)
if err != nil {
return nil, err
}
claims, ok := token.Claims.(jwt.MapClaims)
if ok && token.Valid {
accessUuid, ok := claims["accessUuid"].(string)
if !ok {
return nil, err
}
userId, err := strconv.ParseInt(fmt.Sprintf("%.f", claims["userId"]), 10, 64)
if err != nil {
return nil, err
}
return &models.AccessDetails{
AccessUuid: accessUuid,
UserId: userId,
}, nil
}
return nil, err
}
//校验token
func VerifyToken(r *http.Request) (*jwt.Token, error) {
tokenStr := ExtractToken(r)
token, err := jwt.Parse(tokenStr, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method :%v", token.Header["alg"])
}
return []byte(os.Getenv("ACCESS_SECRET_rt")), nil
})
if err != nil {
return nil, err
}
return token, nil
}
参考链接
源码地址