golang实现jwt

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
}

参考链接

源码地址

你可能感兴趣的:(golang实现jwt)