登录用户中心(用户登录那点事儿)

最近和同事一起打羽毛球总是感觉跟不上节奏,我思考再三后得出结论,一定是我的拍子不行,因为我的技术肯定是没有问题的。

登录用户中心(用户登录那点事儿)(1)

OK,知道了原因之后我果断打开淘宝,搜索尤尼克斯,接着页面便出现了很多选择,我选择了林丹同款,点击之后跳出了一个登录页面。哈,原来我还没有登陆啊。

登录用户中心(用户登录那点事儿)(2)

这简单,熟练地输入账号密码完成登录,接着页面出现了拍子的详细信息。好的,现在就让我来看看这块拍子都有什么特点……

登录用户中心(用户登录那点事儿)(3)

现在让我们倒退,把画面定格在登录页面,当我的鼠标点击登录按钮后,都发生了什么。

登录用户中心(用户登录那点事儿)(4)

发生的事情是,浏览器把我输入的信息发送给了淘宝的服务器,来确定我是否输入了正确的账号密码,如果验证通过,服务器会发送一个凭证给浏览器,浏览器把它存起来,以后每次需要向服务器取数据都要带上这个凭证,这就像是人的身份证一样。

好了,下面开始说点实在的。通常服务器返回的那个东西叫做sessionId,浏览器会把它存在cookie里,同时服务器上保存了我们的登录状态,但是需要sessionId这把钥匙才能获取。这样做的好处是,信息都存在服务器端,服务器可以掌控一切,比如它可以突然让我们强制退出登录。但缺点也是显而易见,服务器端的压力会增大,因为要使用很多内存来存储用户的登录状态。于此相对应的,还有一种方法是,把用户的登录状态存储在浏览器端,用数字签名的方式保证数据不被篡改,这时浏览器存储的就不是简单的sessionid了,而是具体的用户登录状态,比如用户的id。此时,服务器端只要验证浏览器传过来的凭证是否有效就可以了,它自己则不再存储用户的登录状态。到这,今天的主角就该出场了,它就是JWT,也就是存在浏览器中的那个东西,让我们看看它究竟长啥样。

PART01

什么是JWT

JWT是JSON Web Token的简称,它是一种互联网开放标准。它被设计用来在两方之间传输声明(claims),在我们日常应用中,就是在服务器和客户端之间传递认证信息,也就是我们常说的token。在设计中,它被要求是结构紧凑,URL安全的,所以可以放在URL、请求头和body中。通常的做法是放在请求头的Authorization中,这也是很多第三方库采用的做法。JWT既可以是加密的也可以是不加密的,如果不加密的话,请不要放敏感信息。

PART 02

什么是JWS

简单来说,JWT加签名就变成了JWS(json Web Signature),所以我们通常用的有签名的JWT其实准确的叫法是JWS。这里之所以提到JWS,是为了下面所涉及到的概念,通常我们不用深入了解,想要深入了解请参考RFC7515。

PART 03

Payload

JWT的结构概括来说可以分成3部分,中间用(.)连接:

  • Header
  • Payload
  • Signature

所以一个典型的jwt类似xxxxxx.yyyyyy.zzzzzz

Header

JWT的header是一个json对象,通常是下面这个样子:

{

"typ":"JWT",

"alg":"HS256"

}

typ属性表示这个令牌的类型,如果是JWT令牌,这个值是JWTalg属性表示后面会用到的签名的算法,HS256表示HMAC SHA256。

一般情况下,有这两个属性就够了,但其实还可以有其它属性。实际上这两个属性是定义在JWS的header中的,JWT只是拿过来用。所以想知道header里还有哪些属性,请查看JWS的header属性,除此之外,payload中的属性也可以放到header中,特殊情况下有用。最后要把这个json使用base64url加密后,才能放到JWT中,作为JWT的第一部分。

Payload

JWT的payload部分也是一个json对象,JWT规定了7个字段供选用,分别是:

  • iss(Issuer):签发人
  • exp(Expiration Time):过期时间
  • sub(Subject):主题
  • aud(Audience):受众
  • nbf(Not Before):生效时间
  • iat(Issued At):签发时间
  • jti(JWT ID):编号

以上这些属性都是可选的,除了这些,我们还可以自定义一些属性。下面是一个padyload的例子:

{

"iss":"http://localhost",

"iat":1661503024,

"exp":1661506624,

"nbf":1661503024,

"jti":"jloZNwoyTlIW3OE2",

"sub":1,

"prv":"23bd5c8949f600adb39e701c400872db7a5976f7"

}

和header一样,最后用base64url加密后放到JWT的第二部分。

需要注意的是,如果加了签名,那么这部分信息确实无法被更改了,但是依然可以被任何人看到,所以敏感信息不要放到paylaod中,加密过的信息除外。

Signature

Signature是对前面2部分的签名,目的是防止数据被篡改。首先我们需要一个密钥,这个密钥放在服务器端,然后使用Header里指定的算法(通常是HS256),按照下面的规则生成签名:

HMACSHA256(base64UrlEncode(header) "." base64UrlEncode(payload), secret)

把这个签名也用base64url加密,然后放到JWT的第三部分,一个完整的JWT就生成了。

PART 04

base64Url

由于JWT有可能被放到url中,所以这里对Header和Payload的加密不是普通的base64算法,而是在此基础上做了一些修改。首先依然是用普通的base64算法对字符串加密,然后把加密的字符串中的" "替换成"-","/"替换成"_",最后去掉字符串中的"="。

PART 05

JWT的结构

1. JWT是无状态的,所以服务器不会保存用户的登录信息,这可以减轻服务器端的压力

2. 用户先在设备A进行登录,后又在设备B进行登录,此时A设备的登录状态不会退出。

3. JWT一旦签发,除非过期或者更换了密钥,否者一直有效,正因如此,JWT的过期时间最好不要太长。

登录用户中心(用户登录那点事儿)(5)

以上,JWT的重点内容都在这里了,虽然不多但是要理解其中任何一个细节都不是容易的事,如果你觉得我讲得还不错,就给我点个赞吧。最后祝所有看完这篇文章的朋友都能实现自己的理想,事业有成,家庭幸福。

本文所有文字版权均属“宝略科技”,更多内容请搜索关注【宝略科技】微信公众号~

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页