springboot+jwt实现token登陆权限认证
本文内容纲要:
-一前言
-二jwt实现登陆认证流程
-三相关介绍jwt
-3.1jwt组成
-3.2jwt优点
-四jwt用户登陆发放token
-4.1pom.xml
-4.2jwt工具类
-4.3用户实体
-4.4Controller
-4.5测试
-五jwt登陆拦截认证
-5.1自定义拦截器
-5.2service
-5.3拦截器配置
-5.4Controller
-5.5测试
-六官网链接
一前言
此篇文章的内容也是学习不久,终于到周末有时间码一篇文章分享知识追寻者的粉丝们,学完本篇文章,读者将对token类的登陆认证流程有个全面的了解,可以动态搭建自己的登陆认证过程;对小项目而已是个轻量级的认证机制,符合开发需求;更多精彩原创内容关注公主号知识追寻者,读者的肯定,就是对作者的创作的最大支持;
二jwt实现登陆认证流程
- 用户使用账号和面发出post请求
- 服务器接受到请求后使用私钥创建一个jwt,这边会生成token
- 服务器返回这个jwt给浏览器
- 浏览器需要将带有token的jwt放入请求头
- 每次手到客户端请求,服务器验证该jwt的token
- 验证成功返回响应的资源给浏览器。否则异常处理
三相关介绍jwt
3.1jwt组成
JWT的token由三段信息构成的,将这三段信息文本用.
连接一起就构成了JWT字符串;
-
Header头部(包含了令牌的元数据,并且包含签名和或加密算法的类型)
-
Payload负载
-
Signature签名/签证
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1ODI4OTc4NDUsInVzZXJuYW1lIjoienN6eHoifQ.vyiExkFWCCmQA3PFYL0jJfIiYGWubngqB0WcgmtHOxg
3.2jwt优点
- 简洁(Compact):可以通过
URL
,POST
参数或者在HTTPheader
发送,数据量小,传输速度快 - 自包含(Self-contained):负载中包含了所有用户所需要的信息,避免多次查询数据库
- .因为
Token
是以JSON
加密的形式保存在客户端的,所以JWT
是跨语言支持; - 不需要在服务端保存会话信息,适用于分布式与微服务;
四jwt用户登陆发放token
4.1pom.xml
项目构件如下
-
springboot2.1;
-
jwt3.4.0;
-
maven3.5
-
jdk1.8
-
postman接口测试
org.springframework.boot spring-boot-starter-webcom.auth0 java-jwt 3.4.0 org.projectlombok lombok true
4.2jwt工具类
jwt工具类中有三个方法,分别是生成数字签名用于用户首次登陆时发送jwt给客户端;其次是校验方法,用于拦截器拦截所有规则内的url,每个请求都必须带有服务器发送的jwt,经过验证后才放行请求;最后一个获得用户名的方法用于查询密钥,在验证jwt时作为参数传入;
/**
*@Authorlsc
*<p>JWT工具类</p>
*@Param
*@Return
*/
publicclassJwtUtil{
//Token过期时间30分钟
publicstaticfinallongEXPIRE_TIME=30*60*1000;
/**
*@Authorlsc
*<p>校验token是否正确</p>
*@Paramtoken
*@Paramusername
*@Paramsecret
*@Returnboolean
*/
publicstaticbooleanverify(Stringtoken,Stringusername,Stringsecret){
try{
//设置加密算法
Algorithmalgorithm=Algorithm.HMAC256(secret);
JWTVerifierverifier=JWT.require(algorithm)
.withClaim("username",username)
.build();
//效验TOKEN
DecodedJWTjwt=verifier.verify(token);
returntrue;
}catch(Exceptionexception){
returnfalse;
}
}
/**
*@Authorlsc
*<p>生成签名,30min后过期</p>
*@Param[username,secret]
*@Returnjava.lang.String
*/
publicstaticStringsign(Stringusername,Stringsecret){
Datedate=newDate(System.currentTimeMillis()+EXPIRE_TIME);
Algorithmalgorithm=Algorithm.HMAC256(secret);
//附带username信息
returnJWT.create()
.withClaim("username",username)
.withExpiresAt(date)
.sign(algorithm);
}
/**
*@Authorlsc
*<p>获得用户名</p>
*@Param[request]
*@Returnjava.lang.String
*/
publicstaticStringgetUserNameByToken(HttpServletRequestrequest){
Stringtoken=request.getHeader("token");
DecodedJWTjwt=JWT.decode(token);
returnjwt.getClaim("username")
.asString();
}
}
4.3用户实体
实体中包含用户名,和密码,一切从简;
/**
*@Authorlsc
*<p></p>
*/
@Data
publicclassSysUser{
privateStringusername;
privateStringpassword;
}
4.4Controller
表现层代码用户用户登陆认证,认证成功后发放token给客户端;
/**
*@Authorlsc
*<p></p>
*/
@RestController
publicclassSysUserController{
@PostMapping(value="/login")
publicMap<String,Object>login(@RequestBodySysUsersysUser){
Map<String,Object>map=newHashMap<>();
Stringusername=sysUser.getUsername();
Stringpassword=sysUser.getPassword();
//省略账号密码验证
//验证成功后发送token
Stringtoken=JwtUtil.sign(username,password);
if(token!=null){
map.put("code","200");
map.put("message","认证成功");
map.put("token",token);
returnmap;
}
map.put("code","403");
map.put("message","认证失败");
returnmap;
}
}
4.5测试
测试url
postmanpost请求测试参数如下
{
"username":"zszxz",
"password":"zszxz"
}
返回内容如下
{
"code":"200",
"message":"认证成功",
"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1ODI4OTc4NDUsInVzZXJuYW1lIjoienN6eHoifQ.vyiExkFWCCmQA3PFYL0jJfIiYGWubngqB0WcgmtHOxg"
}
五jwt登陆拦截认证
基于前面已经实现jwt登录认证后发放token给客户端;本节内容就是将token放入请求头中发送请求给服务器;服务器使用拦截器拦截请求对token进行验证;验证成功请求通过,否则请求资源失败;
5.1自定义拦截器
自定义拦截器JwtInterceptor,实现HandlerInterceptor接口,每次请求到达之前都会验证token是否有效;
/**
*@Authorlsc
*<p>token验证拦截器</p>
*/
@Component
publicclassJwtInterceptorimplementsHandlerInterceptor{
@Autowired
SysUserServicesysUserService;
@Override
publicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler)throwsException{
//从http请求头中取出token
Stringtoken=request.getHeader("token");
//如果不是映射到方法直接通过
if(!(handlerinstanceofHandlerMethod)){
returntrue;
}
if(token!=null){
Stringusername=JwtUtil.getUserNameByToken(request);
//这边拿到的用户名应该去数据库查询获得密码,简略,步骤在service直接获取密码
booleanresult=JwtUtil.verify(token,username,sysUserService.getPassword());
if(result){
System.out.println("通过拦截器");
returntrue;
}
}
returnfalse;
}
@Override
publicvoidpostHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler,ModelAndViewmodelAndView)throwsException{
}
@Override
publicvoidafterCompletion(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler,Exceptionex)throwsException{
}
}
5.2service
/**
*@Authorlsc
*<p>模拟查询数据库获得账号密码</p>
*/
@Service
publicclassSysUserService{
publicStringgetPassword(){
return"zszxz";
}
}
5.3拦截器配置
拦截器配置中主要定义拦截请求规则,将拦截器注入WebMvcConfigurer;cors跨域处理;
/**
*@Authorlsc
*<p>拦截器配置</p>
*@Param
*@Return
*/
@Configuration
publicclassInterceptorConfigimplementsWebMvcConfigurer{
/**
*@Authorlsc
*<p>设置拦截路径</p>
*@Param[registry]
*@Returnvoid
*/
@Override
publicvoidaddInterceptors(InterceptorRegistryregistry){
registry.addInterceptor(authenticationInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/login");
}
/**
*@Authorlsc
*<p>将拦截器注入context</p>
*@Param[]
*@Returncom.zszxz.jwt.interceptor.JwtInterceptor
*/
@Bean
publicJwtInterceptorauthenticationInterceptor(){
returnnewJwtInterceptor();
}
/**
*@Authorlsc
*<p>跨域支持</p>
*@Param[registry]
*@Returnvoid
*/
@Override
publicvoidaddCorsMappings(CorsRegistryregistry){
registry.addMapping("/**")
.allowedOrigins("*")
.allowCredentials(true)
.allowedMethods("GET","POST","DELETE","PUT","PATCH","OPTIONS","HEAD")
.maxAge(3600*24);
}
}
5.4Controller
表现层接口用于拦截亲求测试
/**
*@Authorlsc
*<p></p>
*/
@RestController
publicclassTestController{
@GetMapping(value="/api/test")
publicStringget(){
return"zszxz";
}
}
5.5测试
测试urlhttp://localhost:8080/api/test
发送get请求给服务器,带有请求头,key为token,value为用户首次登陆时返回的token串;
测试返回内容如下
zszxz
六官网链接
https://jwt.io/introduction/
源码关注公主号或者作者专栏说明即可获得;
本文内容总结:一前言,二jwt实现登陆认证流程,三相关介绍jwt,3.1jwt组成,3.2jwt优点,四jwt用户登陆发放token,4.1pom.xml,4.2jwt工具类,4.3用户实体,4.4Controller,4.5测试,五jwt登陆拦截认证,5.1自定义拦截器,5.2service,5.3拦截器配置,5.4Controller,5.5测试,六官网链接,
原文链接:https://www.cnblogs.com/zszxz/p/12380618.html