WEB应用的认证策略之JWT |
您所在的位置:网站首页 › jwt中的jti › WEB应用的认证策略之JWT |
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,如下: .. Headerheader 是一个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长这个样子: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6IuW8oOS4iSIsIm5iZiI6MTYyNTAzNDYyOSwiZXhwIjoxNjI1MDM2NDI5LCJpYXQiOjE2MjUwMzQ2Mjl9.rqwOXVmP_WuacQMUGRlRa0X9AowWQ5FAsLP6OAa94fo此时,我们可以去网站 jwt.io 将其转换成原始数据,更清晰的感受一下各个部分的结构: 一般客户端收到 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 |