zoukankan      html  css  js  c++  java
  • 在 GoLang 中使用 jwt 进行认证

    JWT 介绍

    JWT 即 JSON Web Token,是用 JSON 形式安全传输信息的方法。

    我们可以在 jwt.io 上在线解析 token,可以清楚看懂 JWT 的数据结构。

    对 JWT 解码,可以得到以下内容:

    • Header:TOKEN 的类型,就是JWT,签名的算法,如 HMAC、 SHA256
    • Payload:携带的信息,比如用户名、过期时间等,一般叫做 Claim
    • Signature:签名,是由header、payload 和你自己维护的一个 secret 经过加密得来的。

    JWT 可以设置过期时间,它的应用主要有:

    • Access Token:添加到 HTTP 请求的 header 中,进行用户认证。加上过期时间可以让 token 被恶意截获后,黑客只有短暂的时间攻击。

    • Refresh Token:用来给客户端申请新的 Access Token 或者 Refresh Token。比 Access Token 有更长过期时间。

    一般服务端生成 JWT 并返回给客户端时,要放在 cookie里,并且加上 HttpOnly 的标记,意味着这个 cookie不能被 JS获取,这样可以防止 XSS 攻击。

    Go语言中 JWT 的生成、验证

    使用 jwt-go 库生成 JWT。

    import github.com/dgrijalva/jwt-go
    
    func CreateToken(uid, secret string) (string, error) {
      at := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
    	"uid":  uid,
    	"exp":  time.Now().Add(time.Minute * 15).Unix(),
      })
      token, err := at.SignedString([]byte(secret))
      if err != nil {
         return "", err
      }
      return token, nil
    }
    
    

    通常客户端传输 JWT 是通过 header 中的 Authorization 字段,好处是避免了 CORS攻击。并且使用 Bearer 模式。也就是:

    Authorization: Bear eyJhbGciO...
    

    在 grpc 中,可以将 JWT 放在 metadata 中:

    ctx = metadata.NewOutgoingContext(ctx, metadata.Pairs("authorization", "Bearer "+token))
    res, _ := client.Call(ctx, ..)
    

    在服务端的验证:

    // 忽略 ok为假的情况
    incomingContext, ok := metadata.FromIncomingContext(ctx)
    value, ok := incomingContext["authorization"]
    uid, err := ParseToken(value[0])
    

    解析也需要用 jwt-go 库的函数。

    // token: "eyJhbGciO..."
    func ParseToken(token string, secret string) (string, error) {
    	claim, err := jwt.Parse(token, func(token *jwt.Token) (interface{}, error) {
    		return []byte(secret), nil
    	})
    	if err != nil {
    		return "", err
    	}
    	return claim.Claims.(jwt.MapClaims)["uid"].(string)
    }
    

    我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=2qjttvtxcaqsw

  • 相关阅读:
    [Golang学习笔记] 06 程序实体3 类型断言和类型转换
    [Golang学习笔记] 05 程序实体2 作用域访问权限和变量重声明
    [Golang学习笔记] 04 程序实体1 变量声明
    [Golang学习笔记] 03 库源码文件
    virgo-tomcat-server的生产环境线上配置与管理
    virgo-tomcat-server最大并发连接数的修改
    linux系统下kvm虚拟机的安装
    关于virgo-tomcat-server-3.6.0.RELEASE配置文件修改说明
    关于在Linux下apache-maven的安装
    H3C系列之三层交换机文件管理
  • 原文地址:https://www.cnblogs.com/flipped/p/12973557.html
Copyright © 2011-2022 走看看