简介
jwt(json web token),主要用在跨域认证的问题
JWT原理
在https://jwt.io/ 这个网站可以进行jwt的encode 和decode,encode和decode分别如下


jwt组成
通过decode出来的数据,可以看到jwt由三部分组成
1.HEADER (ALGORITHM & TOKEN TYPE)
2.PAYLOAD (DATA)
3.SIGNATURE (SIGNATURE)
Header
Header 部分是一个 JSON 对象,描述 JWT 的元数据,通常是下面的样子。
{ "alg": "HS256", "typ": "JWT" }
上面代码中,alg
属性表示签名的算法(algorithm),默认是 HMAC SHA256(写成 HS256);typ
属性表示这个令牌(token)的类型(type),JWT 令牌统一写为JWT
。
最后,将上面的 JSON 对象使用 Base64URL 算法(详见后文)转成字符串。
Payload
Payload 部分也是一个 JSON 对象,用来存放实际需要传递的数据。JWT 规定了7个官方字段,供选用。
iss (issuer):签发人
exp (expiration time):过期时间
sub (subject):主题
aud (audience):受众
nbf (Not Before):生效时间
iat (Issued At):签发时间
jti (JWT ID):编号
Signature
Signature 部分是对前两部分的签名,防止数据篡改。
首先,需要指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄露给用户。然后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256),按照下面的公式产生签名。
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
算出签名以后,把 Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用"点"(.
)分隔,就可以返回给用户。
生成流程
-
将header和payload两个格式的json 分别进行base64URL编码
-
生成的字符串用.分割,生成了前两部分
-
最后一部分通过是通过:前两段生成的字符串+header里面的加密算法+ 秘钥。
校验流程
通过前面两段base64生成的字符串 ,还有header里面的加密算法,加上密钥,最后生成的字符串 和 原来的的字符串是否相等,来检查jwt是否被篡改。
golang-jwt
type MyCliams struct {
Username string `json:"username"`
jwt.StandardClaims
}
const TokenExpireDuration = time.Hour * 2
var MySecurt = []byte("x14nch911")
//生成token
func GenToken(username string) (string, error) {
c := MyCliams{
username,
jwt.StandardClaims{
ExpiresAt: time.Now().Add(TokenExpireDuration).Unix(),
Issuer: "my-project",
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, c)
return token.SignedString(MySecurt)
}
// 校验token
func ParseToken(tokenString string) (*MyCliams, error) {
//解析token
token, err := jwt.ParseWithClaims(tokenString, &MyCliams{}, func(token *jwt.Token) (i interface{}, err error) {
return MySecurt, nil
})
if err != nil {
fmt.Println(err)
return nil, err
}
if claims, ok := token.Claims.(*MyCliams); ok && token.Valid {
return claims, nil
}
return nil, errors.New("invalid token")
}