cookie和session以及令牌的区别


前言

http是无状态协议,与自己主机不同,http本身并不能判断你在访问了本页面之前还访问了哪个页面,说通俗一点,就是页面本身并不能记录你之前的浏览记录或者操作记录。

最直接的需求就是登录需求,当我们需要完成登录的操作时,就要记录我们的登录信息,从而达到一次登录,一直访问的效果,不然用户每次跳转页面都要重新登录,体验感极差。

要做到这一点,我们就要用到会话跟踪技术。

而cookie 、session、令牌,这些都是会话跟踪技术。


一、cookie

1.1、cookie是什么?

当客户端给服务器端发送请求后,服务器端在响应数据的时候:
=> 服务器端会自动生成一个cookie,并将其响应给浏览器。
=>客户端在接收到响应回来的数据之后,会自动将cookie存储在浏览器本地。
=> 在后续的请求中,客户端每次访问服务器,都会携带cookie到服务器端。

在这里插入图片描述

假如这个cookie命令写在登录页面上,当客户端访问了登录页面,并且访问成功,服务器就会提供一个cookie响应给客户端浏览器,后续客户端在访问的时候,只要携带了这个cookie就说明曾经登录过。

1.2、设置cookie:

设置cookie需要用到HttpServletResponse接口,但是不建议直接实现接口或者创建实现类对象,建议以参数的形式存在~
代码如下(示例):

 @GetMapping("/c1")
    public void cookieAddTest(HttpServletResponse httpServletResponse){
        //设置cookie

        httpServletResponse.addCookie(new Cookie("id","10086"));
        httpServletResponse.addCookie(new Cookie("name","zhangsan"));
        httpServletResponse.addCookie(new Cookie("password","123456"));
    }

在这里插入图片描述
addCookie( ) 需要一个cookie对象,直接new一个就好了,cookie对象又需要两个参数,分别是name和value,是不是很像map,没错就是键值对的形式,一个键对应一个值。直接启动! 我们看一下浏览器的响应,记得打开F12噢 ( 部分笔记本用户是fn+F12 )
在这里插入图片描述

在浏览器的响应头里面,就可以看到我们刚才设置的cookie了。

1.3、获取cookie

呐我们设置了cookie,后端程序能不能拿到呢?怎么拿呢?
直接上代码(示例):

@GetMapping("/c2")
    public void cookieGetTest(HttpServletRequest httpServletRequest){
        Cookie[] cookies = httpServletRequest.getCookies();
        for (Cookie cookie : cookies) {
            System.out.println(cookie.getName()+":"+cookie.getValue());
        }
    }

使用HttpServletRequest 的getCookies( ) 就可以获取所有的cookie对象了,访问c2后,结果直接打印在控制台的效果就是这样的
在这里插入图片描述

1.4、cookie 的优缺点

优点:
Http协议中支持的技术,浏览器自动进行。
缺点:
①移动端(安卓、iOS)不支持cookie
②不安全,用户可以手动禁用cookie,并且可以修改 (科学手段)
③cookie无法跨域。

二、session

2.1、session是什么?

session的底层还是cookie,但与之不同的是:cookie是保存到浏览器本地,本身并不安全,而session是保存在服务器端的,每次访问服务器端,服务器端就会生成一个session对象,保存到服务器端。然后响应给客户端一个JSESSIONID。下一次客户端来访问时,就会携带这个JSESSIONID,服务端就根据这个id去查找对应的session对象,如果匹配成功,说明曾经登录过,匹配失败就说明未曾登录。

第一次请求:
在这里插入图片描述
后续请求:
在这里插入图片描述

2.2、设置session

设置session需要用到HttpSession接口
代码如下(示例):

 @GetMapping("/s1")
    public void session1(HttpSession session) {
        session.setAttribute("loginUser", "tom"); //往session中存储数据
        session.setAttribute("loginUser", "Jerry"); //往session中存储数据
        session.setAttribute("loginUser1", "tom1"); //往session中存储数据
    }

session也是key - value键值对的形式~
话不读说,直接启动!看效果:
在这里插入图片描述
这个JSESSIONID就会响应到客户端,客户端下一次访问的时候就会携带这个JSESSIONID,来匹配刚才的session对象。

2.3、获取session

获取session需要用到HttpSession接口,但是一般情况下我们都先用HttpServletRequest去获取HttpSession对象,然后再获取session。因为上一个DispatcherServlet获取完可以直接传递。
代码如下(示例):

@GetMapping("/s2")
    public void session2(HttpServletRequest request) {
        //获取HttpSession对象
        HttpSession session = request.getSession();
        //从session中获取数据
        Object loginUser = session.getAttribute("loginUser1");
    }

注意看浏览器请求头中的信息,cookie里面就携带了刚才生成的JSESSIONID,并且直接输出loginUser就可以在控制台看到session封装的东西啦~

在这里插入图片描述

2.4、session的优缺点

优点:
底层是cookie,cookie有的session都有,并且还解决了cookie不安全的特点。
缺点:
①服务端集群状态下无法直接使用session
②移动端无法使用cookie
③用户可以自己禁用cookie
④cookie无法跨域

三、令牌

3.1、令牌是什么

令牌,听名字感觉高大上的,但是其本质就是一个字符串,通过一系列算法加密而成。当客户端首次访问某个特定的服务器端时,会生成一个令牌,后续每次访问都会带着这个令牌一同前来,服务器端会校验令牌的真实性、合法性。
在这里插入图片描述
以JWT令牌为例:

3.2、JWT令牌的组成:

jwt令牌由三部分组成 : A.B.C

其中
A是(Header):令牌的算法以及令牌的类型 比如 :HS256算法,JWT
B是(Payload):记录了令牌中真实的数据,比如:id、username、password等等
C是(Signature):HS256算法加密(Base64加密(A)+ Base64加密 (B) )

签名(Signature)的目的就是为了防止jwt令牌被篡改,一旦令牌中有任何一部分的任何一个字符被修改了,在校验令牌的时候都会失效,直接报错。

3.3、生成JWT令牌

想要生成JWT令牌,就需要先导入jwt的依赖~
依赖如下:(注意版本问题噢~)

	<dependency>
		<groupId>io.jsonwebtoken</groupId>
		<artifactId>jjwt</artifactId>
		<version>0.9.1</version>
	</dependency>

导入依赖之后,就可以直接生成令牌啦~

String name = Jwts.builder()
.setClaims(map)
.signWith(SignatureAlgorithm.HS256, "name")
.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 30))
.compact();

分别解释一下这几个点点点是什么意思~

Jwts.bulider( ) : 可以理解为生成器的意思

.setClaims(map) : 真实的数据,一般是键值对的形式

.signWith(SignatureAlgorithm.HS256, “name”) :设置算法、令牌名字(签名)

.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 30)) : 设置令牌存活时间,1000毫秒= 1秒,以此类推

.compact() :结构、契约,可以理解为以上述条件生成令牌

3.4、解析令牌

能创建,自然能解析!

Claims claims = Jwts.parser()
.setSigningKey("令牌的名字(签名)")
.parseClaimsJws("jwt令牌")
.getBody();

分别解释一下这几个点点点是什么意思:

Jwts.parser() : 调用JWT的解析器

.setSigningKey(“令牌的名字”) : 设置签名,可以理解为获得jwt令牌的名字

.parseClaimsJws(“jwt令牌”) : 解析传入进来的令牌代码

.getBody(); : 获取jwt令牌体

3.5、JWT令牌的优缺点

优点:
①支持PC端、移动端
②解决了集群环境下的认证问题
③减轻了服务器的存储压力
缺点:
相比于cookie和session,JWT令牌需要手动实现(生成、传递、校验)等等

其实,使用JWT令牌更多时候都是以工具类的形式出现


总结

充电时刻

总的来说,cookie、session、令牌这三种会话跟踪技术,都是在访问了一个特殊页面后,给客户端浏览器打一个标签,在标签有效期内,都不用重复做这件事。

cookie的标签存储在客户端的电脑上,并且访问的时候在浏览器的控制台,所有信息一览无遗,非常的不安全。

而session的存在,就是来弥补cookie的不足的。因为session的底层就是cookie,只不过与之不同的是,cookie的标签存在客户端浏览器上,session的标签存在服务器端上。

但是cookie与session本身都有局限性,无法处理集群、跨域、移动端的标记,非常的不方便。因此就有了令牌。

以JWT令牌为例,它既实现了跨域,有实现了移动端的标记,而且信息还是层层加密,非常的安全,非常的可靠。

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值