jwt和传统session的区别?
jwt和传统session的区别?
传统的session认证
1、用户向服务器发送用户名和密码。
2、服务器验证通过后,在当前对话(session)里面保存相关数据,比如用户角色、登录时间等等。
3、服务器向用户返回一个 session_id,写入用户的 Cookie。
4、用户随后的每一次请求,都会通过 Cookie,将 session_id 传回服务器。
5、服务器收到 session_id,找到前期保存的数据,由此得知用户的身份。
基于session认证所显露的问题。
这种模式的问题在于,扩展性(scaling)不好。单机当然没有问题,如果是服务器集群,或者是跨域的服务导向架构,就要求 session 数据共享,每台服务器都能够读取 session。
举例来说,A 网站和 B 网站是同一家公司的关联服务。现在要求,用户只要在其中一个网站登录,再访问另一个网站就会自动登录,请问怎么实现?
一种解决方案是 session 数据持久化,写入数据库或别的持久层。各种服务收到请求后,都向持久层请求数据。这种方案的优点是架构清晰,缺点是工程量比较大。另外,持久层万一挂了,就会单点失败。
另一种方案是服务器索性不保存 session 数据了,所有数据都保存在客户端,每次请求都发回服务器。JWT 就是这种方案的一个代表。
基于token的鉴权机制
基于token的鉴权机制类似于http协议也是无状态的,它不需要在服务端去保留用户的认证信息或者会话信息。这就意味着基于token认证机制的应用不需要去考虑用户在哪一台服务器登录了,这就为应用的扩展提供了便利。
流程上是这样的:
- 用户使用用户名密码来请求服务器
- 服务器进行验证用户的信息
- 服务器通过验证发送给用户一个token
- 客户端存储token,并在每次请求时附送上这个token值
- 服务端验证token值,并返回数据
这个token必须要在每次请求时传递给服务端,它应该保存在请求头里, 另外,服务端要支持CORS(跨来源资源共享)策略,一般我们在服务端这么做就可以了Access-Control-Allow-Origin: *。
JWT长什么样?
JWT是由三段信息构成的,将这三段信息文本用.链接一起就构成了Jwt字符串。就像这样:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
- 第一部分我们称它为头部(header)
- 第二部分我们称其为载荷(payload, 类似于飞机上承载的物品)
- 第三部分是签证(signature).
header
jwt的头部承载两部分信息:
{'typ': 'JWT','alg': 'HS256'}
声明类型
,这里是jwt
声明加密的算法
通常直接使用 HMAC SHA256
然后将头部进行base64加密(该加密是可以对称解密的),构成了第一部分.
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
playload
载荷就是存放有效信息的地方。这个名字像是特指飞机上承载的货品,这些有效信息包含三个部分
- 标准中注册的声明
- 公共的声明
- 私有的声明
- 标准中注册的声明 (建议但不强制使用) :
iss: jwt签发者
sub: 主题
aud: 接收jwt的一方
exp: jwt的过期时间,这个过期时间必须要大于签发时间
nbf: 生效时间
iat: 签发时间
jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。
- 公共的声明 :
公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息.但不建议添加敏感信息,因为该部分在客户端可解密. - 私有的声明 :
私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息。
定义一个payload:
{"sub": "1234567890","name": "John Doe","admin": true
}
然后将其进行base64加密,得到Jwt的第二部分。
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9
signature
Signature
- header (base64后的)
- payload (base64后的)
- secret
这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分。
将这三部分用.连接成一个完整的字符串,构成了最终的jwt
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
注意:
secret是保存在服务器端的,jwt的签发生成也是在服务器端的,secret就是用来进行jwt的签发和jwt的验证,所以,它就是你服务端的私钥,在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了。
jjwt如何应用
我们如果把token理解问一个携带信息的加密字符,那大致可以分为3个步骤
- 向token中加入信息
- 把信息加密
- 解密获取信息
项目结构
jwt核心代码
public class JwtHelper {/*** token 过期时间, 单位: 秒. 这个值表示 30 天*/private static final long TOKEN_EXPIRED_TIME = 30 * 24 * 60 * 60;/*** jwt 加密解密密钥*/private static final String JWT_SECRET = "MDk4ZjZiY2Q0NjIxZDM3M2NhZGU0ZTgzMjYyN2I0ZjY=";public static final String jwtId = "tokenId";/*** 创建JWT*/public static String createJWT(Map<String, Object> claims, Long time) {SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256; //指定签名的时候使用的签名算法,也就是header那部分,jjwt已经将这部分内容封装好了。Date now = new Date(System.currentTimeMillis());SecretKey secretKey = generalKey();long nowMillis = System.currentTimeMillis();//生成JWT的时间//下面就是在为payload添加各种标准声明和私有声明了JwtBuilder builder = Jwts.builder() //这里其实就是new一个JwtBuilder,设置jwt的body.setClaims(claims) //如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的.setId(jwtId) //设置jti(JWT ID):是JWT的唯一标识,根据业务需要,这个可以设置为一个不重复的值,主要用来作为一次性token,从而回避重放攻击。.setIssuedAt(now) //iat: jwt的签发时间.signWith(signatureAlgorithm, secretKey);//设置签名使用的签名算法和签名使用的秘钥if (time >= 0) {long expMillis = nowMillis + time;Date exp = new Date(expMillis);builder.setExpiration(exp); //设置过期时间}return builder.compact();}/*** 验证jwt*/public static Claims verifyJwt(String token) {//签名秘钥,和生成的签名的秘钥一模一样SecretKey key = generalKey();Claims claims;try {claims = Jwts.parser() //得到DefaultJwtParser.setSigningKey(key) //设置签名的秘钥.parseClaimsJws(token).getBody();} catch (Exception e) {claims = null;}//设置需要解析的jwtreturn claims;}/*** 由字符串生成加密key** @return*/public static SecretKey generalKey() {String stringKey = JWT_SECRET;byte[] encodedKey = Base64.decodeBase64(stringKey);SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");return key;}/*** 根据userId和openid生成token*/public static String generateToken(String openId, Integer userId) {Map<String, Object> map = new HashMap<>();map.put("userId", userId);map.put("openId", openId);return createJWT(map, TOKEN_EXPIRED_TIME);}}
Controller层
@RestController
public class LoginController {@RequestMapping("/user/login")public String login() {String jwtToken = JwtHelper.generateToken("123",456);return jwtToken;}@RequestMapping("user/hello")public String user(){return "hello";}
}
过滤器的使用
public class MyFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request =(HttpServletRequest)servletRequest;HttpServletResponse response = (HttpServletResponse)servletResponse;String token = request.getHeader("authorization"); //获取请求传来的tokenClaims claims = JwtHelper.verifyJwt(token); //验证tokenif (claims == null) { response.getWriter().write("token is invalid");}else {filterChain.doFilter(request,response);}}@Overridepublic void destroy() {}
}
过滤器的加载
@Configuration
public class BeanRegisterConfig {@Beanpublic FilterRegistrationBean createFilterBean() {//过滤器注册类FilterRegistrationBean registration = new FilterRegistrationBean();registration.setFilter(new MyFilter());registration.addUrlPatterns("/user/hello"); //需要过滤的接口return registration;}
}
启动项目:
访问localhost:8080/user/hello
如下图:
携带token访问/user/hello
on = new FilterRegistrationBean();
registration.setFilter(new MyFilter());
registration.addUrlPatterns("/user/hello"); //需要过滤的接口
return registration;
}
}
`启动项目:` 访问`localhost:8080/user/hello`
如下图:[外链图片转存中...(img-fH69CdgR-1621396178496)]
携带token访问/user/hello
![img](https://img-blog.csdnimg.cn/img_convert/511780e64c485ad8a259fc8fcdb5e244.png)
jwt和传统session的区别?相关推荐
- Token ,Cookie和Session的区别
Cookie cookie 是一个非常具体的东西,指的就是浏览器里面能永久存储的一种数据,仅仅是浏览器实现的一种数据存储功能. cookie由服务器生成,发送给浏览器,浏览器把cookie以kv形式保 ...
- cookie 和session 的区别详解
转自 https://www.cnblogs.com/shiyangxt/archive/2008/10/07/1305506.html 这些都是基础知识,不过有必要做深入了解.先简单介绍一下. 二者 ...
- 图解Nosql(hbase)与传统数据库的区别
图解Nosql(hbase)与传统数据库的区别 http://www.aboutyun.com/thread-7804-1-1.html (出处: about云开发) 问题导读: 1.nosql数据库 ...
- 大数据统计分析毕业设计_大数据分析与传统统计分析的区别
大数据分析与传统统计分析的区别:其一是数据分析时不再进行抽样,而是采用全样本(n=all):其二是分析方法,不再采用传统的假设检验. 一.统计方法: 大数据的应用,解决了一般统计方法上主要误差来源:抽 ...
- Cookie 与Session 的区别
Cookie 与Session 的区别(转载) 原地址: http://www.cnblogs.com/shiyangxt/archive/2008/10/07/1305506.html 两个都可以用 ...
- cookie,session的区别和联系(补充token)
文章目录 1 http为什么是无状态的 2 cookie 和session 的区别详解 3 token 参考: 备注: 博客文章仅限于学习,禁止商用 1 http为什么是无状态的 2 cookie 和 ...
- cookie 和session 的区别
session是保存在服务器端的,cookie是保存在客户端的. 二者的定义: 当你在浏览网站的时候,WEB 服务器会先送一小小资料放在你的计算机上,Cookie 会帮你在网站上所打的文字或是一些选择 ...
- nodejs的koa中cookie和session的使用,cookie和session的区别
1.cookie是存储于访问者的计算机中的数据,用于同一浏览器访问同一域的时候共享数据 2.HTTP是无状态协议.也就是说:当你浏览了一个页面,然后跳转到同一个网站的另一个页面,服务器无法认识到这是同 ...
- 知识图谱·概念与技术--第1章学习笔记--知识图谱概述--知识图谱的概念,与传统语义网络的区别
知识图谱·概念与技术--第1章学习笔记--知识图谱概述--知识图谱的概念,与传统语义网络的区别 知识图谱的概念,与传统语义网络的区别 狭义概念 作为语义网络的内涵 与传统语义网络的区别 优点 缺点 与 ...
- UEFI和传统引导的区别有哪些
背景 前两天装机时,用U盘启动进行安装系统时,发现还原ghost系统后怎么也进入不了windows10开机界面,一直显示: 在U盘中去使用引导修复,也失败了,后来重新将系统盘进行分区,变成MBR格式, ...
最新文章
- Laravel5中Cookie的使用
- HTML5新增表单验证
- 如何对加载的数个模型只进行transform呢
- nginx中js修改不生效的问题
- java+arrayblockquene_java集合(五)Queue集合之ArrayBlockingQueue 详解
- Effective Java之避免创建不必要的对象(五)
- php基础小结,PHP基础学习小结
- matlab eval 不显示,matlab中 eval(command); 运算符无效的问题
- json怎么读取数据库_如何:使用Json插入数据库并从中读取
- python小测验3_python基础小测试
- css 清空ios端_H5移动端开发常见的问题处理
- [转载] python中count()、values_counts()、size()函数
- Opera的一个神奇功能
- python库之SnowNLP(自然语言处理)
- 解决Windows11能登录QQ微信,但不可以使用浏览器上网
- Transaction-based classification and detection approach for Ethereum smart contract
- 有监督学习、无监督学习、半监督学习、强化学习
- NSSCTF部分复现
- 2022年全球市场柠檬酸酯总体规模、主要生产商、主要地区、产品和应用细分研究报告
- 研究7——发展与应用
热门文章
- c语言详解 蔡勒(Zeller)公式计算某一天是星期几 极其方便
- 谈谈持久连接——HTTP权威指南读书心得(五)
- 39万的一节课:让你悟透“近朱者赤,近墨者黑”的道理
- 值-结果参数(socket编程中的函数举例)
- java for语句
- 利用Oracle Enterprise Manager Cloud Control 12c创建DataGuard Standby
- 如何利用【百度地图API】,制作房产酒店地图?(上)——制作自定义标注和自定义信息窗口...
- 8.业务架构·应用架构·数据架构实战 --- 技术方案书
- 12.微服务设计 --- 总结
- 21.实例 --- location