Cookie,Session,Token来进行身份认证


Cookie的流程图如下:

在这里插入图片描述


因为,Cookie是不安全的,因为我们的密码用户都是存在Cookie中的,就算进行了加密,某种程度上也是暴露的。如下:

  • 例如:我不用钻研你这个加密算法是什么,我只需要拿到你的这个cookie里面加密后的东西,直接用,直接发到你的服务器上面。照样可以登录你的信息。

因此,就有了Session。


总结:

  • Cookie大部分的使用都是作为一个载体来传输数据的(数据载体)。

3. Session

==========================================================================


Session会话机制是基于Cookie的。

  • 1.用户发送http请求协议,进行登录。

  • 2.登录成功后,服务器创建一个SessionID,Max-age(存活时间)等Session信息,并且对含有SessionID的Cookie进行签名,之后将Cookie放到Set-Cookie的响应头中。

  • 3.浏览器之后每次想服务器发送请求的时候都会携带这个Session信息,放到Cookie中,再将该Cookie存在一个名为Cookie的请求头中,发给服务器。

  • 4.服务器进行验证。

在这里插入图片描述


但是,随着集群的架构出现,多台服务器之间必须要共享Session会话才行!

因此,就有了将Session会话信息存储到数据库中,一般数据库选择redis非关系型。

但是,如果数据库崩溃了,那么就会彻底影响session了。

在这里插入图片描述


总结:

  • session是存储在服务器端的,用户每次发送请求都携带一个保存session信息的的cookie。

4. 为什么使用JWT?

============================================================================


cookie和session的缺点:

  • session存储在服务端内存中

  • 集群环境中需要额外处理。

  • cookie跨域读写不方便。

而JWT,token的优点就是弥补了上面的缺点。因为,token主要来解决前后端分离的场景。

5. JWT(JSON Web Token)的实现过程

===========================================================================================


JWT任何语言都可以使用!因为JWT是一种思想。具体的语言实现操作才是JWT实现。

token的英文直译是令牌的意思。

JWT全称叫做JSON Web Token,一般我们叫做token实现登录验证。

  • 1.用户发送请求协议进行登录。

  • 2.之后服务器会生成一个JWT和JWT签名密文,服务器会将JWT发送给浏览器,浏览器可以通过Cookie或者Storage本地存储的形式来存储。

  • 3.浏览器再次发送请求,就会把JWT的信息存到一个名为token的请求头中,发送给服务器。

  • 4.服务器进行验证。

![在这里插入图片描述](https

必看视频!获取2024年最新Java开发全套学习资料 备注Java

😕/img-blog.csdnimg.cn/99954f5d3f7a44a7a858a10d644686fa.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASVRfSG9sbWVz,size_20,color_FFFFFF,t_70,g_se,x_16)

JWT需要的salt盐作用就是加强加密的复杂度,这么破解起来就更加麻烦,当然这个“盐”越长越复杂,加密后破解起来就越麻烦。


JWT是由三部分组成的:

在这里插入图片描述

在这里插入图片描述


总结:

  • token是诞生在服务器,但保存在浏览器这边的。可以放到cookie或storage中。持有token就像持有令牌一样可以允许访问服务器。

6. 官方实现JWT的多种方式

===============================================================================


JWT官方网站

我们去Libraries中,找到Java相关的JWT。

在这里插入图片描述


这里我们就是使用两种官方的JWT实现:

  • java-jwt

  • jjwt-root

在这里插入图片描述

在这里插入图片描述

7. JWT的实现第一种:java-jwt包的使用

=========================================================================================


第一步:导包,导依赖。

com.auth0

java-jwt

3.18.3

第二步:调用JWT。

  • jwt三部分组成:header.payload.signature。

  • 需要我们配置的也就只有payload,通过withClaim来配置。

import java.util.Calendar;

import org.junit.Test;

import com.auth0.jwt.JWT;

import com.auth0.jwt.JWTCreator.Builder;

import com.auth0.jwt.JWTVerifier;

import com.auth0.jwt.algorithms.Algorithm;

import com.auth0.jwt.exceptions.AlgorithmMismatchException;

import com.auth0.jwt.exceptions.InvalidClaimException;

import com.auth0.jwt.exceptions.SignatureVerificationException;

import com.auth0.jwt.exceptions.TokenExpiredException;

import com.auth0.jwt.interfaces.DecodedJWT;

import com.sun.org.apache.bcel.internal.generic.ALOAD;

public class JavaJwtTest {

//hmac256摘要算法,跟md5类似,只是这个hmac256需要指定key,通常这个key叫做salt盐。

String key = “123456abc”;

/*

  • 测试java-jwt生成token字符串

  •   jwt三部分组成:
    
  •   	header.payload.signature
    

*/

@Test

public void testGenerateToken() {

Calendar calendar = Calendar.getInstance();

calendar.add(Calendar.SECOND, 60*5);

//claim英文直译:声明意思

Builder builder = JWT.create()

//withClaim中设定的就是payload的内容。

.withClaim(“userid”, 123)

.withClaim(“userName”, “itholmes”)

.withClaim(“url”, “https//www.itholmes.top”)

//设置过期时间

.withExpiresAt(calendar.getTime());

String token = builder.sign(Algorithm.HMAC256(key));

System.out.println(token);

}

//校验

@Test

public void testVerify() {

String token = “eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyTmFtZSI6Iml0aG9sbWVzIiwiZXhwIjoxNjQ2NzUxMTk3LCJ1c2VyaWQiOjEyMywidXJsIjoiaHR0cHMvL3d3dy5pdGhvbG1lcy50b3AifQ.e7y_9iO_jtVXo90qaq5H0aiUmg29I9XeJqAgUCDb1zo”;

JWTVerifier build = JWT.require(Algorithm.HMAC256(key)).build();

DecodedJWT verify = null;

try{

verify = build.verify(token);

System.out.println(verify);

}catch(TokenExpiredException e) {

System.out.println(“该token已经过期。”);

}catch (SignatureVerificationException e) {

System.out.println(“签名不一致”);

}catch (AlgorithmMismatchException e) {

System.out.println(“签名算法不匹配”);

}catch (InvalidClaimException e) {

System.out.println(“payload不可用”);

}catch (Exception e) {

System.out.println(“其他错误校验失败”);

}

System.out.println(verify);

if(verify!=null) {

//asInt()方法转换类型。

Integer userid = verify.getClaim(“userid”).asInt();

String userName = verify.getClaim(“userName”).asString();

String url = verify.getClaim(“url”).asString();

System.out.println();

}

}

}

8. JWT的实现第二种:jjwt包的使用

=====================================================================================


第一步:同样导包导依赖。

io.jsonwebtoken

jjwt

0.9.1

第二步:Jwts调用。

import java.util.Calendar;

import java.util.HashMap;

import java.util.Map;

import org.junit.Test;

import io.jsonwebtoken.Claims;

import io.jsonwebtoken.JwtBuilder;

import io.jsonwebtoken.Jwts;

import io.jsonwebtoken.SignatureAlgorithm;

public class JJwtTest {

String key=“123435abc”;

//通过jjwt生成token字符串

@Test

public void testGenerateToken() {

//过期时间

Calendar calendar = Calendar.getInstance();

calendar.add(Calendar.SECOND, 60*5);

//创建payLoad的私有声明(根据特定的业务需要添加)

Map<String, Object> claims = new HashMap<String, Object>();

claims.put(“userid”,123);

claims.put(“userName”,“itholmes”);

claims.put(“url”,“https//www.itholmes.top”);

JwtBuilder builder = Jwts.builder()

//设置payLoad,传入的是map类型

.setClaims(claims)

//设置过期时间

.setExpiration(calendar.getTime())

//设置签名使用的签名算法和签名使用的秘钥

.signWith(SignatureAlgorithm.HS256, key);

String compact = builder.compact();

System.out.println(compact);

}

//校验token

@Test

public void testVerify() {

String token=“eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyTmFtZSI6Iml0aG9sbWVzIiwiZXhwIjoxNjQ2NzUyNjcxLCJ1c2VyaWQiOjEyMywidXJsIjoiaHR0cHMvL3d3dy5pdGhvbG1lcy50b3AifQ.6M9yg8iGutEgoYNv97n3GV5_o29iL2YXbrdpME_xtXc”;

Claims claims = Jwts.parser()

.setSigningKey(key)//设置签名秘钥

.parseClaimsJws(token).getBody();//设置需要解析的jwt

Integer userId = claims.get(“userid”,Integer.class);

String userName = claims.get(“userName”,String.class);

String url = claims.get(“url”,String.class);

System.out.println();

}

}

9. 封装JWT的包装类,方便以后使用

===================================================================================


package com.itholmes.utils;

import java.util.Calendar;

import com.auth0.jwt.JWT;

import com.auth0.jwt.JWTCreator.Builder;

import com.auth0.jwt.algorithms.Algorithm;

import com.auth0.jwt.exceptions.AlgorithmMismatchException;

import com.auth0.jwt.exceptions.InvalidClaimException;

import com.auth0.jwt.exceptions.SignatureVerificationException;

import com.auth0.jwt.exceptions.TokenExpiredException;

import com.auth0.jwt.interfaces.Claim;

import com.auth0.jwt.interfaces.DecodedJWT;

import com.fasterxml.jackson.core.JsonProcessingException;

import com.fasterxml.jackson.databind.JsonMappingException;

import com.fasterxml.jackson.databind.ObjectMapper;

import com.itholmes.bean.User;

public class JwtUtil {

//jwt的key也就是salt盐

private static final String key = “www.itholmes.top”;

//生成token

public static String generateToken(User user) throws JsonProcessingException {

//使用jackson来生成json字符串方便存取

ObjectMapper jackson = new ObjectMapper();

String user_string = jackson.writeValueAsString(user);

//通过calendar设置过期时间

Calendar calendar = Calendar.getInstance();

calendar.add(Calendar.DAY_OF_YEAR, 7);

//创建builder对象

Builder builder = JWT.create()

//设置payload内容

.withClaim(“userInfo”, user_string)

.withExpiresAt(calendar.getTime());

//生成token

String token = builder.sign(Algorithm.HMAC256(key));

return token;

}

//校验token

public static DecodedJWT verify(String tokenToVerity) {

DecodedJWT verify = null;

try{

verify = JWT

.require(Algorithm.HMAC256(key))

.build()

.verify(tokenToVerity);

}catch(TokenExpiredException e) {

e.printStackTrace();

System.out.println(“该token已经过期。”);

}catch (SignatureVerificationException e) {

e.printStackTrace();

System.out.println(“签名不一致”);

}catch (AlgorithmMismatchException e) {

e.printStackTrace();

System.out.println(“签名算法不匹配”);

}catch (InvalidClaimException e) {

e.printStackTrace();

System.out.println(“payload不可用”);

}catch (Exception e) {

e.printStackTrace();

System.out.println(“其他错误校验失败”);

}

return verify;

最后

针对以上面试题,小编已经把面试题+答案整理好了

最新大厂必问微服务面试题汇总:SpringCloud、Boot、Dubbo

最新大厂必问微服务面试题汇总:SpringCloud、Boot、Dubbo

最新大厂必问微服务面试题汇总:SpringCloud、Boot、Dubbo

面试专题

image

除了以上面试题+答案,小编同时还整理了微服务相关的实战文档也可以分享给大家学习

image

image

image
System.out.println(“签名不一致”);

}catch (AlgorithmMismatchException e) {

e.printStackTrace();

System.out.println(“签名算法不匹配”);

}catch (InvalidClaimException e) {

e.printStackTrace();

System.out.println(“payload不可用”);

}catch (Exception e) {

e.printStackTrace();

System.out.println(“其他错误校验失败”);

}

return verify;

最后

针对以上面试题,小编已经把面试题+答案整理好了

[外链图片转存中…(img-lEaZOts1-1716406150287)]

[外链图片转存中…(img-SLoDpZnS-1716406150288)]

[外链图片转存中…(img-9Ip4vosI-1716406150288)]

面试专题

[外链图片转存中…(img-gG5Y6oOi-1716406150288)]

除了以上面试题+答案,小编同时还整理了微服务相关的实战文档也可以分享给大家学习

[外链图片转存中…(img-O5zIXYJ4-1716406150289)]

[外链图片转存中…(img-DZFG9jma-1716406150289)]

[外链图片转存中…(img-LrWoL45l-1716406150289)]

  • 19
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值