WEB应用的认证策略之JWT

您所在的位置:网站首页 jwt中的jti WEB应用的认证策略之JWT

WEB应用的认证策略之JWT

2023-03-09 05:41| 来源: 网络整理| 查看: 265

Web应用在浏览器和服务器之间的传输数据时,服务器有时候需要识别用户并根据不同的用户给予不同的回复。下面介绍一下Web应用识别用户和验证权限的解决方案。

关于HTTP传输

服务器和浏览器之间通过HTTP协议来传输数据,而HTTP协议是一个无状态协议,这种情况下,服务器就像一个特殊银行柜台,不断的接收用户的请求事务,其特点主要如下:

主要特点:不管请求的人是谁,也不管他之前是否请求过,更不会去记住是谁请求;它只管处理具体的事情,处理完就结束,然后继续下一个。用户验证

1. 验证身份最简单的方法就是客户端传输用户名和密码

于是,我们可以这么干:每次请求信息的时候都提供用户名和密码。但是,难道每次都让用户输入用户名和密码,再发送请求?用户要疯掉了...又或者,直接把用户名和密码保存在浏览器中,当每次发送请求的时候,再自动带上用户名和密码。这...风险有点大...

2. 更为安全高效的方法是:在用户登陆后,服务器给用户一把钥匙

用户每次访问是都带上钥匙;服务器收到钥匙后进行验证钥匙的有效性;

这样就避免了用户传输用户名和密码等敏感信息,也提高了服务器的效率,不用每次都和数据库交互验证。

密钥解决方案 方案一,传统的方法 session 认证

认证流程如下:

1) 在登陆页面,用户向服务器发送用户名和密码。 2) 服务器验证通过后,保存相关数据(用户名、角色、登录有效期、登陆状态等),通常这些信息保存到session 当中;然后服务器把对应的 session_id 通过 Cookie 返回给客户端(Cookie 的名字通常是 session_id)。 3) 后面用户的每次请求都会自动带上这个Cookie,发送回服务器。 4) 最后服务器根据这个 session_id 找到事先保存好的数据信息来确认访问的用户身份。

方案的优点:

a) 服务器只需要验证一次用户名和密码,减少和数据库的交互次数; b) 用户信息(session)一般存储在缓存或者缓存数据库中,获取和验证数据更快; c) 客户端(浏览器)只需要存储session_id,没有任何敏感数据;

方案的缺点:

a) 由于 session 存储在服务器的内存,当用户多时服务器的内存开销会比较大; b) 扩展性差,单服务器很方便,但是多服务器时就要在服务器间共享 session,麻烦; c) CSRF问题,由于客户端和服务器之间的 session_id 是通过 cookie 来传输的,容易被截获; d) 有些客户端传输 cookie 不方便,特别是跨域时;

2. 方案二,JWT ( JSON WEB TOKENS ), 更优

认证流程如下:

1) 在登陆页面,用户向服务器发送用户名和密码; 2) 服务器验证通过后,返回一个令牌(Token)给客户端;这个 Token 存有编码后的用户数据,此用户数据没有加密,但是 token 中有签名,可供服务器验证; 3) 客户端收到后把令牌保存起来,等下次访问时带上传给服务器; 4) 服务器收到 Token 后,验证 JWT 的有效性,有效则继续访问;

方案的优点:

a) Token 和 http 协议一样也是无状态的,在服务器端不需要缓存用户信息(session),减少缓存的使用,更不用在多服务器之间共享用户session登陆信息,简单、高效; b) 可以很方便实现单点登陆功能(SSO);

这个方案可以更高效,可以省去很多资源和繁琐的处理逻辑。

但是要注意的是,如果这个 token 被截取了就会有被盗用身份的风险。我们需要根据对风险的接受程度来调整token 的有效期,有效期越短,风险就越低;只要在很短是有效期内,就算被盗用了,风险也不会很大。

关于 JWT

什么是JWT?

JSON Web Token (JWT),是一个开发的标准(RFC 7519),定义了网络端之间如何安全地传输信息的方式。协议是基于JSON的,传输的信息(Token)是一个JSON Object。因为这个Token是有数字签名的,所以传输的信息是可验证的,安全可靠。JWT可以是单密钥使用HMAC算法签名,也可以是非对称的双密钥使用RSA或ECDSA签名。

JWT的结构 ( JWT由三部分组成 )

1) Header (头部) 2) Payload (有效载荷) 3) Signature (签名)

这三部分经过Base64编码后按顺序用 “.” 连接起来便是一个jwt,如下:

.. Header

header 是一个JSON,通常包括两个部分:token 的类型(jwt)和签名用到的算法如 HMAC SHA256 或者 RSA。具体如下:

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

这个JSON在经过Base64Url编码后就是Header了。

2. Payload

Payload,即 JWT 的主要声明信息,包含了需要传输的用户信息及实际应用中的额外数据,也是一个 JSON 对象,对象中的每一个字段就是一个声明。JWT 协议中规定了7个标准的注册字段,如下:

1) iss ( Issuer ):JWT签发人 2) sub ( Subject ):JWT主题 3) aud ( Audience ):JWT受众 4) exp ( Expiration Time ):JWT过期时间 5) nbf ( Not Before ):JWT生效时间 6) iat ( Issued At ):JWT签发时间 7) jti ( JWT ID ):JWT的唯一身份标识

除了这几个标准的字段,还可以添加自己需要的字段。JSON的样子如下:

{ "unique_name": "张三", "exp": 1625036429, "iat": 1625034629 }

这个JSON同样经过Base64Url编码后就是第二部分Payload。一般JWT 默认是不加密的,任何人都可以读到,所以不要把敏感信息放进去。

3. Signature

这个部分是由前面两个部分的加密字符串。生成过程如下:

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

三部分合计来就是一个JWT,如下图:

组成 JWT 的三个部分

最后一个JWT长这个样子:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6IuW8oOS4iSIsIm5iZiI6MTYyNTAzNDYyOSwiZXhwIjoxNjI1MDM2NDI5LCJpYXQiOjE2MjUwMzQ2Mjl9.rqwOXVmP_WuacQMUGRlRa0X9AowWQ5FAsLP6OAa94fo

此时,我们可以去网站 jwt.io 将其转换成原始数据,更清晰的感受一下各个部分的结构:

验证结果JWT的实际实现(应用)

一般客户端收到 token 后,每次发送请求的时候在请求头( Header )里加入 Authorization,并加上 Bearer 标注(注意Bearer后面要有个空格):

Authorization: Bearer // 主要 Bearer后面是要有一个空格的!!! headers: { 'Authorization': 'Bearer ' + token }

当后台服务器收到 token 后,根据之前生成token的密钥(secret)解密,获取到的信息对比token的签名两个部分进行验证,验证通过则 token 通过,服务器将允许访问。

参考文档:

jwt.io 官方详解


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3