jwt简介和在go中的简单使用

打印 上一主题 下一主题

主题 985|帖子 985|积分 2955

什么是 JSON Web 令牌?

JSON Web 令牌 (JWT) 是一种开放标准 (RFC 7519),它界说了一种紧凑且自包罗的方式,用于将信息作为 JSON 对象在各方之间安全地传输。此信息是经过数字署名的,因此可以验证和信托。可以使用密钥(使用 HMAC 算法)或使用 RSAECDSA 的公钥/私钥对对 JWT 举行署名。
尽管 JWT 可以加密以在各方之间提供机密性,但我们将重点先容署名令牌。署名令牌可以验证其中包罗的声明的完整性,而加密令牌则对其他方隐蔽这些声明。当使用公钥/私钥对令牌举行署名时,署名还会证明只有持有私钥的一方是签订私钥的一方。
何时应使用 JSON Web 令牌?

以下是 JSON Web 令牌有用的一些情况:


  • 授权:这是使用 JWT 的最常见场景。用户登录后,每个后续哀求都将包罗 JWT,答应用户访问该令牌答应的路由、服务和资源。单点登录是当今广泛使用 JWT 的一项功能,因为它的开销小,并且能够轻松地跨差别域使用。
  • 信息互换:JSON Web 令牌是在各方之间安全地传输信息的好方法。由于 JWT 可以署名(比方,使用公钥/私钥对),因此您可以确保发件人是他们所声称的身份。别的,由于署名是使用标头和有用负载盘算的,因此您还可以验证内容是否未被篡改。
什么是 JSON Web 令牌结构?

在其紧凑形式中,JSON Web 令牌由三个部分组成,由点 () 分隔,它们是:.


  • 页眉
  • 有用载荷
  • 署名
因此,JWT 通常如下所示。
  1. xxxxx.yyyyy.zzzzz
复制代码
让我们分解差别的部分。
页眉

标头通常由两部分组成:令牌的类型(JWT)和正在使用的署名算法,比方 HMAC SHA256 或 RSA。
比方:
  1. {
  2.   "alg": "HS256",
  3.   "typ": "JWT"
  4. }
复制代码
然后,此 JSON 经过 Base64Url 编码以形成 JWT 的第一部分。
有用载荷

令牌的第二部分是有用负载,其中包罗声明。声明是关于实体(通常是用户)和其他数据的声明。 有三种类型的声明:已注册公共私有声明。


  • 已注册的声明:这些是一组预界说的声明,不是强制性的,但发起使用,以提供一组有用的、可互操作的声明。其中一些是:iss(颁发者)、exp(过期时间)、sub(主题)、aud(受众)等。
           请注意,声明名称只有三个字符长,因为 JWT 是紧凑的。
  • Public claims:这些声明可以由使用 JWT 的用户随意界说。但为制止辩论,应在 IANA JSON Web 令牌注册表中界说它们,或将其界说为包罗抗辩论定名空间的 URI。
  • 私有声明:这些是自界说声明,用于在同意使用它们的各方之间共享信息,既不是注册声明,也不是公开声明。
一个示例有用负载可以是:
  1. {
  2.   "sub": "1234567890",
  3.   "name": "John Doe",
  4.   "admin": true
  5. }
复制代码
然后,对有用负载举行 Base64Url 编码,以形成 JSON Web 令牌的第二部分。
   请注意,对于署名令牌,此信息虽然可以防止篡改,但任何人都可以读取。除非 JWT 已加密,否则不要将机密信息放在 JWT 的 payload 或 header 元素中。
  署名

要创建署名部分,您必须获取编码的标头、编码的有用负载、密钥、标头中指定的算法,并对其举行署名。
比方,如果您想使用 HMAC SHA256 算法,将按以下方式创建署名:
  1. HMACSHA256(
  2.   base64UrlEncode(header) + "." +
  3.   base64UrlEncode(payload),
  4.   secret)
复制代码
署名用于验证消息在整个过程中没有被更改,并且在使用私钥署名的令牌的情况下,它还可以验证 JWT 的发件人是否是它所声称的身份。
把所有的东西放在一起

输出是三个 Base64-URL 字符串,由点分隔,可以在 HTML 和 HTTP 情况中轻松传递,同时与基于 XML 的标准(如 SAML)相比更加紧凑。
下面表现了一个 JWT,该 JWT 对之前的标头和有用负载举行了编码,并使用密钥举行了署名。

在go中的简单使用

下载依赖jwt官方库

  1. go get -u github.com/golang-jwt/jwt/v5
复制代码
创建

创建一个携带用户基本信息的token
  1. // JwtPayLoad jwt中payload数据
  2. type JwtPayLoad struct {
  3.   UserID   uint   `json:"user_id"`
  4.   Username string `json:"username"` // 用户名
  5.   Role     int    `json:"role"`     // 权限  
  6. }
  7. type CustomClaims struct {
  8.   JwtPayLoad
  9.   jwt.RegisteredClaims
  10. }
  11. // GenToken 创建 Token
  12. func GenToken(user JwtPayLoad, accessSecret string, expires int64) (string, error) {
  13.   claim := CustomClaims{
  14.     JwtPayLoad: user,
  15.     RegisteredClaims: jwt.RegisteredClaims{
  16.       ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour * time.Duration(expires))),
  17.     },
  18.   }
  19.   token := jwt.NewWithClaims(jwt.SigningMethodHS256, claim)
  20.   return token.SignedString([]byte(accessSecret))//自定义秘钥,[]byte类型
  21. }
复制代码
RegisteredClaims

RegisteredClaims是一个结构体,可以根据需求选择填写生成的token内容
  1. type RegisteredClaims struct {
  2.     // Issuer (iss) - 签发者
  3.         // the `iss` (Issuer) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.1
  4.         Issuer string `json:"iss,omitempty"`
  5.     // Subject (sub) - 主题/主体
  6.         // the `sub` (Subject) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.2
  7.         Subject string `json:"sub,omitempty"`
  8.     // Audience (aud) - 接收方
  9.         // the `aud` (Audience) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.3
  10.         Audience ClaimStrings `json:"aud,omitempty"`
  11.     // ExpiresAt (exp) - 过期时间,设置为当前时间之后24小时
  12.         // the `exp` (Expiration Time) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.4
  13.         ExpiresAt *NumericDate `json:"exp,omitempty"`
  14.     // NotBefore (nbf) - 生效时间,设置为当前时间
  15.         // the `nbf` (Not Before) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.5
  16.         NotBefore *NumericDate `json:"nbf,omitempty"`
  17.     // IssuedAt (iat) - 签发时间
  18.         // the `iat` (Issued At) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.6
  19.         IssuedAt *NumericDate `json:"iat,omitempty"`
  20.     // ID (jti) - JWT ID,唯一标识符
  21.         // the `jti` (JWT ID) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.7
  22.         ID string `json:"jti,omitempty"`
  23. }
复制代码
验证

  1. // ParseToken 解析 token
  2. func ParseToken(tokenStr string, accessSecret string, expires int64) (*CustomClaims, error) {
  3.   token, err := jwt.ParseWithClaims(tokenStr, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
  4.     return []byte(accessSecret), nil
  5.   })
  6.   if err != nil {
  7.     return nil, err
  8.   }
  9.   if claims, ok := token.Claims.(*CustomClaims); ok && token.Valid {
  10.     return claims, nil
  11.   }
  12.   return nil, errors.New("invalid token")
  13. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

渣渣兔

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表