JWT鉴权 |青训营

121 阅读3分钟

jwt验证

JWT (全称:Json Web Token)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为 JSON 对象在各方之间安全地传输信息。由于此信息是经过数字签名的,因此可以被验证和信任。可以使用秘密(使用HMAC算法)或使用RSA或的公用/专用密钥对对JWT进行签名。

应用

1.授权 一旦用户登录,每个后续请求将包括JWT,从而允许用户访问该令牌允许的路由,服务和资源。单点登录是今广泛使用JWT的一项功能。因为它的开销很小并且可以在不同的域中轻松使用

2.信息交换 JSON Web Token是在各方之间安全地传输信息的好方法。因为可以对JWT进行签名(例如,使用公钥/私钥对),所以您可以确保发件人是他们所说的人。此外,由于签名是使用标头和有效负载计算的,因此您还可以验证内容是否遭到篡改。

流程

1.用户使用账号、密码登录应用,登录的请求发送到 Authentication Server。 2.Authentication Server 进行用户验证,然后创建 JWT 字符串返回给客户端。 3.客户端请求接口时,在请求头带上 JWT。 4.Application Server 验证 JWT 合法性,如果合法则继续调用应用接口返回结果

jwt结构

JWT 一般是这样一个字符串,分为三个部分,以 “.” 隔开

   xxxxx.yyyyy.zzzzz
|jwt头|有效载荷|签名|

header

{
    "alg": "HS256",
    "typ": "JWT"
}

alg 属性表示签名使用的算法,默认为 HMAC SHA256(写为HS256),typ 属性表示令牌的类型,JWT 令牌统一写为JWT。最后,使用 Base64 URL 算法将上述 JSON 对象转换为字符串保存

pyload

JWT 第二部分是 Payload,也是一个 Json 对象,除了包含需要传递的数据,还有七个默认的字段供选择。

  • iss (issuer):签发人/发行人

  • sub (subject):主题

  • aud (audience):用户

  • exp (expiration time):过期时间

  • nbf (Not Before):生效时间,在此之前是无效的

  • iat (Issued At):签发时间

  • jti (JWT ID):用于标识该 JWT

签名

JWT 第三部分是签名。是这样生成的,首先需要指定一个 secret,该 secret 仅仅保存在服务器中,保证不能让其他用户知道。这个部分需要 base64URL 加密后的 header 和 base64URL 加密后的 payload 使用 . 连接组成的字符串,然后通过header 中声明的加密算法 进行加盐secret组合加密,然后就得出一个签名哈希,也就是Signature,且无法反向解密。 最后一步签名的过程,实际上是对头部以及负载内容进行签名,防止内容被窜改。如果有人对头部以及负载的内容解码之后进行修改,再进行编码,最后加上之前的签名组合形成新的JWT的话,那么服务器端会判断出新的头部和负载形成的签名和JWT附带上的签名是不一样的。如果要对新的头部和负载进行签名,在不知道服务器加密时用的密钥的话,得出来的签名也是不一样的

go-jwt 使用

结构体

//载荷结构体
type Pyload struct {
	Name               string `json:"name"`
	Role               string `json:"role"`
	Pnone              string `json:"pnone"`
	jwt.StandardClaims        //标准jwt
}

创建token


func (j *JWT) CreatToken(load Pyload) (string, error) {
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, load)
	return token.SignedString(j.Singkey) //返回被签名的token
}

以载荷创建一个token, 同时指定加密方式使用用户基本信息claims以及签名key(signkey)生成token。

解析token

token, err := jwt.ParseWithClaims(tokenstring, &Pyload{}, func(token *jwt.Token) (interface{}, error) {
		return j.Singkey, nil
	})

以Pyload的格式解析token,Keyfunc在使用时一般都是返回secret密钥,可以根据Token的种类不同返回不同的密钥.