Jwt和Token

简介: Jwt和Token的认识

1、什么是 JWT?


JSON Web Token,通过数字签名的方式,以 JSON 对象为载体,在不同的服务终端之间安全的传输信息。




2、JWT 有什么用?


JWT 最常见的场景就是授权认证,一旦用户登录,后续每个请求都将包含JWT,系统在每次处理用户请求的之前,都要先进行 JWT 安全校验,通过之后再进行处理。




3、JWT 的组成


JWT 由 3 部分组成,用.拼接



eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IlRvbSIsInJvbGUiOiJhZG1pbiIsInN1YiI6ImFkbWluLXRlc3QiLCJleHAiOjE2MjMyMjM2NzUsImp0aSI6ImQ2MTJjZjcxLWI5ZmUtNGMwNy04MzQwLTViOWViZmMyNjExNyJ9.FOS9Y7rYNdc2AOidnSPrgg2XTYePU0yGZ598h2gtabE



这三部分分别是:


  • Header


{
'typ': 'JWT',
'alg': 'HS256'  }


  • Payload



{
"sub": '1234567890',
"name": 'xmp',
"admin":true  }



  • Signature




varencodedString=base64UrlEncode(header) +'.'+base64UrlEncode(payload);
varsignature=HMACSHA256(encodedString, 'secret');

4、优缺点

优点


  • 简洁: 可以通过URL、POST参数或者在HTTP header发送,因为数据量小,传输速度也很快;
  • 自包含:负载中可以包含用户所需要的信息,避免了多次查询数据库;
  • 因为Token是以JSON加密的形式保存在客户端的,所以JWT是跨语言的,原则上任何web形式都支持;
  • 不需要在服务端保存会话信息,特别适用于分布式微服务。

缺点

  • 无法作废已颁布的令牌;
  • 不易应对数据过期。


5、测试

pom.xml    jwt依赖坐标


<dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>3.13.0</version></dependency>


token登录,浏览器f12可以观察到token信息

image.png


6、SpringBoot集成JWT实现token验证

1、pom.xml

jwt坐标

<dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>3.13.0</version><!--版本号可以根据自己的--></dependency>

工具类坐标

<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.20</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.2</version></dependency>

2、代码


生成token


packagecom.example.boot.utils;
importcn.hutool.core.date.DateUtil;
importcn.hutool.core.util.StrUtil;
importcom.auth0.jwt.JWT;
importcom.auth0.jwt.algorithms.Algorithm;
importcom.example.boot.entity.User;
importcom.example.boot.service.IUserService;
importorg.springframework.stereotype.Component;
importorg.springframework.web.context.request.RequestContextHolder;
importorg.springframework.web.context.request.ServletRequestAttributes;
importjavax.annotation.PostConstruct;
importjavax.annotation.Resource;
importjavax.servlet.http.HttpServletRequest;
importjava.util.Date;
@ComponentpublicclassTokenUtils {
privatestaticIUserServicestaticUserService;
@ResourceprivateIUserServiceuserService;
@PostConstructpublicvoidsetUserService() {
staticUserService=userService;
    }
/*** 生成token* author: xmp* date: 2022/5/12* @return*/publicstaticStringgenToken(StringuserId, Stringsign) {
returnJWT.create().withAudience(userId)                                            // 将 user id 保存到 token 里面,作为载荷                .withExpiresAt(DateUtil.offsetHour(newDate(), 2))                    // 2小时后token过期 ===>当前日期加2小时                .sign(Algorithm.HMAC256(sign));                                             // 以 password 作为 token 的密钥    }
/*** 获取当前登录的用户信息** @return user对象*/publicstaticUsergetCurrentUser() {
try {
HttpServletRequestrequest= ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
Stringtoken=request.getHeader("token");
if (StrUtil.isNotBlank(token)) {
StringuserId=JWT.decode(token).getAudience().get(0);
returnstaticUserService.getById(Integer.valueOf(userId));
            }
        } catch (Exceptione) {
returnnull;
        }
returnnull;
    }
}

jwt

packagecom.example.boot.config.interceptor;
importcn.hutool.core.util.StrUtil;
importcom.auth0.jwt.JWT;
importcom.auth0.jwt.JWTVerifier;
importcom.auth0.jwt.algorithms.Algorithm;
importcom.auth0.jwt.exceptions.JWTDecodeException;
importcom.auth0.jwt.exceptions.JWTVerificationException;
importcom.example.boot.common.Constants;
importcom.example.boot.entity.User;
importcom.example.boot.exception.ServiceException;
importcom.example.boot.service.IUserService;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.web.method.HandlerMethod;
importorg.springframework.web.servlet.HandlerInterceptor;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
publicclassJwtInterceptorimplementsHandlerInterceptor {
@AutowiredprivateIUserServiceuserService;
@OverridepublicbooleanpreHandle(HttpServletRequestrequest, HttpServletResponseresponse, Objecthandler) {
Stringtoken=request.getHeader("token");
// 如果不是映射到方法直接通过if(!(handlerinstanceofHandlerMethod)){
returntrue;
        }
// 执行认证if (StrUtil.isBlank(token)) {
thrownewServiceException(Constants.CODE_401, "无token,请重新登录");
        }
// 获取 token 中的 user idStringuserId;
try {
userId=JWT.decode(token).getAudience().get(0);
        } catch (JWTDecodeExceptionj) {
thrownewServiceException(Constants.CODE_401, "token验证失败,请重新登录");
        }
// 根据token中的userid查询数据库Useruser=userService.getById(userId);
if (user==null) {
thrownewServiceException(Constants.CODE_401, "用户不存在,请重新登录");
        }
// 用户密码加签验证 tokenJWTVerifierjwtVerifier=JWT.require(Algorithm.HMAC256(user.getPassword())).build();
try {
jwtVerifier.verify(token); // 验证token        } catch (JWTVerificationExceptione) {
thrownewServiceException(Constants.CODE_401, "token验证失败,请重新登录");
        }
returntrue;
    }
}

拦截,通过判断token是否合法来决定是否需要登录

packagecom.example.boot.config;
importcom.example.boot.config.interceptor.JwtInterceptor;
importorg.springframework.context.annotation.Bean;
importorg.springframework.context.annotation.Configuration;
importorg.springframework.web.servlet.config.annotation.InterceptorRegistry;
importorg.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@ConfigurationpublicclassInterceptorConfigimplementsWebMvcConfigurer {
@OverridepublicvoidaddInterceptors(InterceptorRegistryregistry) {
registry.addInterceptor(jwtInterceptor())
                .addPathPatterns("/**")                                             // 拦截所有请求,通过判断token是否合法来决定是否需要登录                .excludePathPatterns("/user/login", "/user/register", "/**/export", "/**/import");
    }
@BeanpublicJwtInterceptorjwtInterceptor() {
returnnewJwtInterceptor();
    }
}

service层,接口实现类的登录逻辑

@OverridepublicUserDtologin(UserDtouserDTO) {
Userone=getUserInfo(userDTO);
if (one!=null) {
BeanUtil.copyProperties(one, userDTO, true);
//设置tokenStringtoken=TokenUtils.genToken(one.getId().toString(), one.getPassword());
userDTO.setToken(token);
returnuserDTO;
    } else {
thrownewServiceException(Constants.CODE_600, "用户名或密码错误");
    }
}
相关文章
|
4月前
|
JSON JavaScript 前端开发
❤Nodejs 第九章(token身份认证和express-jwt的安装认识)
【4月更文挑战第9天】Node.js第九章介绍了Token身份认证,特别是JWT(JSON Web Token)作为跨域认证的解决方案。JWT由Header、Payload和Signature三部分组成,用于在客户端和服务器间安全传输用户信息。前端收到JWT后存储在localStorage或sessionStorage中,并在请求头中发送。Express-JWT是一个中间件,用于解析JWT。基本用法包括设置secret和algorithms。注意安全问题,避免混合使用不同算法以防止降级攻击。
89 0
|
4月前
|
存储 NoSQL 前端开发
jwt与redis,把生成的token放入redis中进行临时存储
jwt与redis,把生成的token放入redis中进行临时存储
305 0
|
11月前
|
存储 JSON 安全
解锁互联网安全的新钥匙:JWT(JSON Web Token)
解锁互联网安全的新钥匙:JWT(JSON Web Token)
176 0
|
10月前
|
存储 安全 测试技术
快速教你如何使用postman工具进行接口测试?(配置全局token、JWT可用)
快速教你如何使用postman工具进行接口测试?(配置全局token、JWT可用)
361 0
|
1月前
|
存储 JSON JavaScript
震撼!Cookie、Session、Token、JWT 终极对决:揭开 Web 认证的神秘面纱!
【8月更文挑战第13天】Web 开发中,Cookie、Session、Token 和 JWT 常混淆。Cookie 是服务器给客户端的小信息片,如登录状态,每次请求都会返回。Session 则是服务器存储的用户数据,通过 Session ID 追踪。Token 类似通行证,证明客户端身份且可加密。JWT 是结构化的 Token,含头部、载荷及签名,确保数据完整性和安全性。
39 4
|
26天前
|
API
【Azure Developer】记录一段验证AAD JWT Token时需要设置代理获取openid-configuration内容
【Azure Developer】记录一段验证AAD JWT Token时需要设置代理获取openid-configuration内容
|
27天前
|
JSON Java API
【Azure Developer】如何验证 Azure AD的JWT Token (JSON Web 令牌)?
【Azure Developer】如何验证 Azure AD的JWT Token (JSON Web 令牌)?
|
27天前
|
JSON 算法 API
【Azure API 管理】APIM 配置Validate-JWT策略,验证RS256非对称(公钥/私钥)加密的Token
【Azure API 管理】APIM 配置Validate-JWT策略,验证RS256非对称(公钥/私钥)加密的Token
|
1月前
|
存储 开发框架 JSON
ASP.NET Core 标识(Identity)框架系列(二):使用标识(Identity)框架生成 JWT Token
ASP.NET Core 标识(Identity)框架系列(二):使用标识(Identity)框架生成 JWT Token
|
1月前
|
Java Spring
JWT token验证后,通过 ThreadLocal 进行传值
JWT token验证后,通过 ThreadLocal 进行传值
14 0

热门文章

最新文章