基于jwt或session用户鉴权
基于session的用户认证
一、步骤
- 用户输入其登录信息(账号密码)
- 服务器验证信息是否正确,并创建一个session,然后将其存储在数据库中
- 服务器为用户生成一个sessionId,将具有sesssionId的Cookie将放置在用户浏览器中
- 在后续请求中,会根据数据库验证sessionId,如果有效,则接受请求
- 一旦用户注销应用程序,会话将在客户端和服务器端都被销毁
二、如何使用
拿到sessionId后,在发请求的时候cookie中携带上它发送到服务端,服务端进行验证,验证失败,返回未授权,重新授权;验证成功后;返回结果
基于jwt的用户认证
一、步骤
- 用户输入其登录信息(账号密码)
- 服务器验证信息是否正确,并返回已签名的token
- token储在客户端,例如存在local storage或cookie中
- 之后的HTTP请求都将token添加到请求头里
- 服务器解码JWT,并且如果令牌有效,则接受请求
- 一旦用户注销,令牌将在客户端被销毁,不需要与服务器进行交互一个关键是,令牌是无状态的。后端服务器不需要保存令牌或当前session的记录。
二、jwt的组成
一个jwt实际上就是一个字符串,它由三部分组成,头部、载荷与签名,这三个部分都是json格式。
头部(Header)
头部用于描述关于该JWT的最基本的信息,例如其类型以及签名所用的算法等。
1{ "typ": "JWT", "alg": "HS256"} 2// 在这里,我们说明了这是一个JWT,并且我们所用的签名算法是HS256算法。
载荷(Payload)
载荷可以用来放一些不敏感的信息。
1{ 2 "iss": "ohn Wu JWT", // 发布者的 url 地址 3 "iat": 1441593502, // 该 jwt 的发布时间;unix 时间戳 4 "exp": 1441594722, // 该 jwt 销毁的时间;unix 时间戳 5 "aud": "www.example.com", // 接受者的 url 地址 6 "sub": "jrocket@example.com", // 该 JWT 所面向的用户,用于处理特定应用,不是常用的字段 7 "from_user": "B", // 8 "target_user": "A" // 9} 10// 这里面的前五个字段都是由JWT的标准所定义的。
- iss: 该JWT的签发者
- sub: 该JWT所面向的用户
- aud: 接收该JWT的一方
- exp(expires): 什么时候过期,这里是一个Unix时间戳
- iat(issued at): 在什么时候签发的
把头部和载荷分别进行Base64编码之后得到两个字符串,然后再将这两个编码后的字符串用英文句号.连接在一起(头部在前),形成新的字符串:
1eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcm9tX3VzZXIiOiJCIiwidGFyZ2V0X3VzZXIiOiJBIn0
签名(signature)
为了得到签名部分,你必须有编码过的 header、编码过的 payload、一个秘钥,签名算法是 header 中指定的那个,然对它们签名即可。
不要在 JWT 的 payload 或 header 中放置敏感信息,除非它们是加密的。
最后,我们将上面拼接完的字符串用HS256算法进行加密。在加密的时候,我们还需要提供一个密钥(secret)。加密后的内容也是一个字符串,最后这个字符串就是签名,把这个签名拼接在刚才的字符串后面就能得到完整的jwt。header部分和payload部分如果被篡改,由于篡改者不知道密钥是什么,也无法生成新的signature部分,服务端也就无法通过,在jwt中,消息体是透明的,使用签名可以保证消息不被篡改。
例如:
1HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret) 2
三、如何使用
在访问受保护的路由或者资源的时候,用户代理(通常是浏览器)都应该带上 JWT,典型的,通常放在 Authorization header 中,用 Bearer schema,例如:Authorization: Bearer <token>
。服务端拿到后,会进行验证,验证正确,返回数据;验证失败,返回未授权。
两者的优缺点
seesion的优缺点
优点:
- 存储安全性高
- 比较可控
缺点:
- 会占用服务器的空间,以及服务器之间同步的问题
- 会受到CSRF攻击
jwt的优点及缺点:
优点:
- 不再占用服务端的空间,减小了服务器端的压力
- jwt的载荷中可以存储一些常用信息,用于交换信息,有效地使用 JWT,可以降低服务器查询数据库的次数
缺点:
- 不安全,任何人拿到token字符串都可以被当作用户
- jwt过长会影响到请求的性能问题
- 不可控,因为是一次性的,导致无法弃用或者续签(较好的解决方案是1、采用两个token,refresh token和access token,access token有效期短,refresh token有效期可以长一点;2、签发新的后废弃旧的,redis处理)