简易抖音实现的jwt详解 | 青训营

59 阅读4分钟

简易抖音实现的jwt详解

jwt

jwt.StandardClaims 是 Go 编程语言中 github.com/dgrijalva/jwt-go 包中的一个结构体。这个结构体通常在 JWT(JSON Web Token)库中用于表示 JWT 规范中定义的标准声明。

以下是 jwt.StandardClaims 在 Go 中的定义:

type StandardClaims struct {
    Audience  string `json:"aud,omitempty"`
    ExpiresAt int64  `json:"exp,omitempty"`
    Id        string `json:"jti,omitempty"`
    IssuedAt  int64  `json:"iat,omitempty"`
    Issuer    string `json:"iss,omitempty"`
    NotBefore int64  `json:"nbf,omitempty"`
    Subject   string `json:"sub,omitempty"`
}

StandardClaims 中的每个字段对应 JWT 规范中的一个标准声明:

  • Audience(aud):表示令牌的目标受众。它指定令牌的预期接收者或接收者类型。
  • ExpiresAt(exp):以 Unix 时间戳表示的令牌过期时间。在此时间之后,令牌不再有效。
  • Id(jti):为令牌提供一个唯一标识符。这可用于防止令牌重放攻击。
  • IssuedAt(iat):表示令牌发出的时间,以 Unix 时间戳表示。
  • Issuer(iss):标识发出令牌的主体。
  • NotBefore(nbf):指定在此时间之前令牌不应被视为有效。
  • Subject(sub):标识令牌的主题,通常表示与令牌关联的用户或实体。

通过填充这些字段的相关信息,可以在 Go 中使用 jwt-go 库创建和验证 JWT。

// MyClaims 自定义声明结构体并内嵌 jwt.StandardClaims
// jwt包自带的jwt.StandardClaims只包含了官方字段,若需要额外记录其他字段,就可以自定义结构体
// 如果想要保存更多信息,都可以添加到这个结构体中

type MyClaims struct {
	UserID int64 `json:"user_id"`
	jwt.StandardClaims
}
// 可以看到我们需要用到一个user_id信息,于是自定义了一个结构体,加上我们需要的信息字段

这段代码是一个用于生成 JWT(JSON Web Token)的函数。以下是该函数的解释:

func GenToken(userID int64) (string, error) {
	// 创建一个我们自己的声明的数据
	c := MyClaims{
		userID,
		jwt.StandardClaims{
			ExpiresAt: time.Now().Add(
				time.Duration(10000) * time.Hour).Unix(), // 过期时间
			Issuer: "ezreal", // 签发人
		},
	}
	// 使用指定的签名方法创建签名对象
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, c)
	// 使用指定的secret签名并获得完整的编码后的字符串token
	return token.SignedString(mySecret)
}

这个函数接受一个 userID 参数,并使用它创建了一个自定义的声明数据 c。该声明数据包括一个自定义的 MyClaims 结构体和一个标准的 jwt.StandardClaims 结构体。

jwt.StandardClaims 结构体中,设置了过期时间 ExpiresAt 为当前时间加上 10000 小时,并设置了签发人 Issuer 为 "ezreal"。在 JWT(JSON Web Token)中,"签发人"(Issuer)是一个标准声明(Standard Claim),用于指示生成或签发该令牌的实体或服务。它表示令牌的发行者身份。

签发人字段的值可以是任何字符串,通常是一个标识符或名称,用于识别生成令牌的实体。例如,如果的应用程序使用 JWT 进行身份验证,可以将签发人字段设置为应用程序的名称或标识符。在验证 JWT 时,接收方可以检查签发人字段以确保令牌是由预期的实体或服务签发的。这有助于确保令牌的真实性和可信度。在上述代码示例中,"ezreal" 被设置为签发人字段的值。可以根据应用程序需求和上下文,选择适合的签发人值。

然后,使用指定的签名方法 jwt.SigningMethodHS256 和声明数据 c 创建了一个签名对象 token

最后,使用指定的密钥 mySecret (用于表示密钥)对签名对象进行签名,并返回完整的编码后的 JWT 字符串。

在提供的代码中,mySecret 是一个字节数组,用于表示密钥。在 JWT 的签名过程中,该密钥被用于对令牌进行签名和验证。

密钥是由自己设置的。密钥应该足够长(至少256位)、难以被猜测或推导出来、定期更换。

在示例代码中,mySecret 被初始化为 []byte("jwt"),表示将字符串 "jwt" 转换为字节数组作为密钥。**请注意,这只是一个示例密钥,并不足够安全。**在实际应用中,您应该使用更长、更随机的密钥来确保令牌的安全性。

建议在实际使用中选择一个更强大和安全的密钥,并采取适当的措施来保护该密钥,例如存储在安全的地方,并限制访问权限。这样可以提高令牌的安全性,并防止未经授权的访问或篡改。

请注意,上述代码中的 MyClaims 结构体和 mySecret 密钥是未定义的,需要根据实际情况进行定义和设置。