(基础)golang+jwt实现用户登录获取token

(基础)golang+jwt实现用户登录获取token

  • 1.根据用户名/密码获取token Service

    JWT(JSON Web Token)是一个非常轻巧的规范。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。

    一个JWT由三部分组成,<font color='red'>头部、载荷 与 签名</font>。

    JWT原理类似我们加盖公章或手写签名的的过程,合同上写了很多条款,不是随便一张纸随便写啥都可以的,必须要一些证明,比如签名,比如盖章。JWT就是通过附加签名,保证传输过来的信息是真的,而不是伪造的;

    载荷:

    包含生成Token时间,过期时间,以及一些身份标识,标准定义了6个字段,载荷json经过base64编码后得到JWT的载荷:

    Payload载荷:
        jti:该jwt的唯一标识
        iss:该jwt的签发者
        iat:该jwt的签发时间
        aud:该jwt的接收者
        sub:该jwt的面向的用户
        nbf:该jwt的生效时间,可不设置,若设置,一定要大于当前Unix UTC,否则token将会延迟生效
        exp:该jwt的过期时间
    
    可自定义其他key-value形式的数据作为载体
    

    签名:

    将头部和载荷用'.'号连接,再加上一串密钥,经过头部声明的加密算法加密后得到签名

    HMACSHA256(
        base64UrlEncode(header) + "." +
        base64UrlEncode(payload),
        secret
    )
    

    JWT Token

    Token=头部+'.'+载荷+'.'+签名

    基本数据结构

    上面是签名的使用例子,下面分析签名的源码实现,首先看下数据结构Token,包含了我们标准中说道的三部分:头部,载荷和签名,此外还带了一个用于存储生成token的字段Raw和校验标识符Valid

    
    // A JWT Token.  Different fields will be used depending on whether you're
    // creating or parsing/verifying a token.
    type Token struct {
        Raw       string                 // The raw token.  Populated when you Parse a                                          token
        Method    SigningMethod          // The signing method used or to be used
        Header    map[string]interface{} // The first segment of the token
        Claims    Claims                 // The second segment of the token
        Signature string                 // The third segment of the token.  Populated when                                         you Parse a token
        Valid     bool                   // Is the token valid?  Populated when you                                             Parse/Verify a token
    }
        
    

    ==定义密钥==

    var tokenApiSecretKey="itxjTokenApi980420"

    获取token

//get token
func GetTokenService(name string,pwd string)(string,error){
  //非空校验
  if common.IsEmpty(name) || common.IsEmpty(pwd) {
      return "",errors.New("账号,密码不能为空")
  }
  token := jwt.New(jwt.SigningMethodHS256)
  claims:=make(jwt.MapClaims)
  claims["jti"]=time.Now().Unix()
  claims["iss"]="itxj"
  claims["iat"]=time.Now()
  claims["aud"]="mam"
  claims["sub"]=name
  claims["nbf"]=time.Now().Unix()
  claims["exp"]=time.Now().Add(time.Hour*time.Duration(24)).Unix()
  claims["cs"]="this is cs claims"
  token.Claims=claims
  tokenStr, err := token.SignedString([]byte(tokenApiSecretKey))
  if err!=nil {
      return "",err
  }
  return tokenStr,nil
}

校验token

//校验token
func ValidateTokenService(tokenStr string)(bool,error){

  token, errByParseToken := jwt.Parse(tokenStr, func(token *jwt.Token) (i interface{}, e error) {

      return []byte(tokenApiSecretKey),nil
  })
  if errByParseToken!=nil {
      return false,errors.New("An invalid Token ")
  }
  if !token.Valid {
      return false,errors.New("fail while invalid Token ")
  }
  return true,nil
}

> 获取校验成功后的token(*jwt.Token)
>
> 
//获取校验并且返回token
func GetValidateTokenService(tokenStr string)(*jwt.Token,error){

  token, er := jwt.Parse(tokenStr, func(token *jwt.Token) (i interface{}, e error) {
      return []byte(tokenApiSecretKey), nil
  })
  if er!=nil {
      return token,er
  }
  return token,nil
}

校验成功后根据key获取token中载荷的数据

//从token claims中提取数据
func GetValFormTokenClaims(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 ""
}
  • 2.测试

    //获取token
      tokenStr, errByGetToken := service.GetTokenService("itxj", "itxj")
      if errByGetToken!=nil {
      fmt.Printf("Get Token error......%s",errByGetToken.Error())
          return
      }
      fmt.Printf("token=%s\n",tokenStr)
      //校验token
      isValidate, errByParseToken := service.ValidateTokenService(tokenStr)
      if errByParseToken!=nil {
          fmt.Printf("Validate Token error......%s",errByParseToken.Error())
          return
      }
      fmt.Printf("token is =%v\n",isValidate)
      //获取校验成功的token
      token, errByGetParseToken := service.GetValidateTokenService(tokenStr)
      if errByGetParseToken!=nil{
          fmt.Printf("Get Validate Token error......%s",errByGetParseToken.Error())
          return
      }
      claims := token.Claims
      fmt.Printf("token.sub=%s;\n",service.GetValFormTokenClaims("sub",claims))
      fmt.Printf("token.cs=%s;\n",service.GetValFormTokenClaims("cs",claims))
    

    码字不易,还望各位哥哥姐姐们关注点赞支持一下

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,869评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,716评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,223评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,047评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,089评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,839评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,516评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,410评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,920评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,052评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,179评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,868评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,522评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,070评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,186评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,487评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,162评论 2 356

推荐阅读更多精彩内容