分享
  1. 首页
  2. 文章

(进阶)goland+jwt实现用户登录获取token

我是不会赢的 · · 1860 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

(进阶)golang+gin+jwt实现用户登录获取token

  • 1.获取token

    POST请求参数

    {
     "name":"xj",
     "pwd":"xj123456"
    }
    

    golang api router:

    
    // 获取Token
    router.POST("/api/getToken", service.GetApiTokenService)
    

    service:

    
    //请求参数结构体
    type GetTokenRequestParam struct {
     Name string `json:"Name"`
     Pwd string `json:"Pwd"`
    }
    //自定义密钥
    var tokenApiSecret = "itxj980420"
    //获取token
    func GetTokenService(c *gin.Context) {
     reqModel := GetTokenRequestParam{}
     errByBind := c.Bind(&reqModel)
     if errByBind != nil {
     c.JSON(http.StatusOK, gin.H{
     "code": http.StatusBadRequest,
     "message": "失败",
     "token": "",
     })
     return
     }
     //参数非空校验
     if common.IsEmpty(reqModel.Name) || common.IsEmpty(reqModel.Pwd) {
     c.JSON(http.StatusOK, gin.H{
     "code": http.StatusBadRequest,
     "message": "账号、密码不能为空!!!",
     "token": "",
     })
     return
     }
     //TODO 添加其他校验如账号密码校验;签名校验等其他自定义参数校验
     //jwt token header 法加密
     token := jwt.New(jwt.SigningMethodHS256)
     //jwt claims 载荷
     //jti:该jwt的唯一标识
     //iss:该jwt的签发者
     //iat:该jwt的签发时间
     //aud:该jwt的接收者
     //sub:该jwt的面向的用户
     //nbf:该jwt的生效时间,可不设置,若设置,一定要大于当前Unix UTC,否则token将会延迟生效
     // exp:该jwt的过期时间 Unix()
     claims := make(jwt.MapClaims)
     claims["jti"] = reqModel.Name + reqModel.Pwd + strconv.Itoa(int(time.Now().Unix()))
     claims["iss"] = "itxj"
     claims["iat"] = time.Now()
     claims["aud"] = reqModel.Name
     claims["sub"] = reqModel.Name
     claims["nbf"] = time.Now().Unix()
     claims["exp"] = time.Now().Add(time.Hour * time.Duration(24)).Unix()
     //Payload载荷
     token.Claims = claims
     //密钥加密
     tokenStr, errBySignToken := token.SignedString([]byte(tokenApiSecret))
     //token 生成失败
     if errBySignToken != nil {
     c.JSON(http.StatusOK, gin.H{
     "code": http.StatusUnauthorized,
     "message": "Error while signing the token!",
     "token": "",
     })
     return
     }
     //success
     c.JSON(http.StatusOK, gin.H{
     "code": http.StatusOK,
     "message": "Success!",
     "token": tokenStr,
     })
     return
    }
    
  • 2.路由中间件校验token

    GET 请求:

    http://ip:port/api/validateToken/:key

    Param: key:载荷中的key

//请求
header 里面
 "Token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ4aiIsImV4cCI6MTU3Nzg2NjU1NiwiaWF0IjoiMjAxOS0xMi0zMVQxNjoxNTo1NS4zNDUyODkrMDg6MDAiLCJpc3MiOiJpdHhqIiwianRpIjoieGppdHhqMTU3Nzc4MDE1NCIsIm5iZiI6MTU3Nzc4MDE1NSwic3ViIjoieGoifQ.zg0FtD4Ovk0GysPSxn2IZfFkvA6KmqbczDPu9zQDFk4"

gin router api

 router.GET("/api/validateToken/:key", service.ValidateTokenService(), service.TestValidateTokenService)

路由中间件—-:校验token是否有效

//路由中间件校验token
func ValidateTokenService() gin.HandlerFunc {
 return func(c *gin.Context) {
 token, err := request.ParseFromRequest(c.Request, request.AuthorizationHeaderExtractor, func(token *jwt.Token) (i interface{}, e error) {
 return []byte(tokenApiSecret), nil
 })
 if err != nil {
 c.Abort()
 c.JSON(http.StatusOK, gin.H{
 "code": http.StatusUnauthorized,
 "message": "fail",
 "error": "Unauthorized!",
 })
 return
 }
 if !token.Valid {
 c.Abort()
 c.JSON(http.StatusOK, gin.H{
 "code": http.StatusUnauthorized,
 "message": "fail",
 "error": "An invalid Token!",
 })
 return
 }
 c.Next()
 }
}

service:

//获取token中的账号
func TestValidateTokenService(c *gin.Context) {
 sub := c.Param("key")
 token, _ := GetTokenFromRequest(c)
 claimsVal := GetValueFromTokenClaims(sub, token.Claims)
 c.JSON(http.StatusOK, gin.H{
 "code": http.StatusOK,
 "message": "成功",
 "claimsVal": claimsVal,
 })
 return
}
//从请求头中获取token
func GetTokenFromRequest(c *gin.Context) (token *jwt.Token, err error) {
 token, err = request.ParseFromRequest(c.Request, request.AuthorizationHeaderExtractor,
 func(token *jwt.Token) (interface{}, error) {
 return []byte(tokenApiSecret), nil
 })
 return token, err
}
//根据key从载荷中获取数据
func GetValueFromTokenClaims(key string, claims jwt.Claims) string {
 v := reflect.ValueOf(claims)
 if v.Kind() == reflect.Map {
 for _, k := range v.MapKeys() {
 value := v.MapIndex(k)
 if fmt.Sprintf("%s", k.Interface()) == key {
 return fmt.Sprintf("%v", value.Interface())
 }
 }
 }
 return ""
}

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:我是不会赢的

查看原文:(进阶)goland+jwt实现用户登录获取token

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
1860 次点击
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏