从spring boot到spring cloud(七)整合JWT(Json Web Token)实现认证实例
时间:2022-09-02 03:00:00
当前端和后端分离开始时,用户权限是通过的session保存。前后端分离后,需要媒体来识别用户的状态token。JWT技术主要封装了用于用户登录鉴权的基本功能
session认证
Session:在计算机中,尤其是在网络应用中,被称为会话控制。Session对象存储特定用户会话所需的属性和配置信息。这样,当用户在应用程序中时Web当页面跳转时,存储在页面之间Session对象中的变量不会丢失,而是存在于整个用户会话中。当用户要求应用程序时 Web如果用户没有在页面上交谈,Web服务器将自动创建 Session对象。服务器将在会话过期或放弃后终止会话。Session 对象最常见的用法之一是存储用户的首选。例如,如果用户表示不喜欢查看图形,则可以存储信息Session对象中。有关使用Session 详情请参考对象ASP管理会话部分的应用程序。注意会话状态只是支持cookie保留在浏览器中。
token认证
Token在计算机身份认证中机身份认证中的含义,在词法分析中标记。一般用作邀请和登录系统。
如果非分布式一般保存在本地整体变量集中,或保存在redis中间。分布式只能保存到redis,否则,其他服务将无法获得。
什么是JWT
JWT(全称:Json Web Token)是开放标准(RFC 7519),它定义了一种紧凑的、自包含的方法,用作JSON对象在各方之间安全传输信息。由于它是数字签名,因此可以验证和信任该信息。
JWT标头由三部分组成(Header)、有效载荷(Payload)和签名(Signature) eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxIiwiZXhwIjoxNjUzODA5MTc3fQ.WZr_z0XCZdm_G9oc_HD-YT2xF0dKyy8257T_2Tk4130 eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9. //标头(Header) eyJzdWIiOiIxIiwiZXhwIjoxNjUzODA5MTc3fQ. //有效载荷(Payload) WZr_z0XCZdm_G9oc_HD-YT2xF0dKyy8257T_2Tk4130 //签名(Signature) Base64(Header).Base64(Payload).HMACSHA256(base64UrlEncode(header) "." base64UrlEncode(payload),secret)
有效载荷(Payload) 业务操作一般可以存储用户的基本信息。
搭建springboot
从spring boot到spring cloud(二)JAVA入门教学,构建基础springboot_lzy711的博客-CSDN博客
查看过去的文章。
maven文件
4.0.0 org.springframework.boot spring-boot-starter-parent 2.5.7 com.aqjyxt aqjyxt 0.0.1-SNAPSHOT aqjyxt Demo project for Spring Boot 1.8 org.springframework.boot spring-boot-starter-web com.alibaba druid-spring-boot-starter 1.1.10 org.mybatis.spring.boot mybatis-spring-boot-starter 2.2.2 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-web io.springfox springfox-boot-starter 3.0.0 com.github.xiaoymin swagger-bootstrap-ui 1.9.6 mysql mysql-connector-java runtime org.springframework.boot spring-boot-starter-test test com.auth0 java-jwt 3.4.0 org.springframework.boot spring-boot-maven-plugin
主要是导入JWT
&nbp;
编写JWT工具类
package com.aqjyxt.bean;
import com.alibaba.druid.util.StringUtils;
import com.aqjyxt.entity.aqjyxt_user;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import java.util.Calendar;
import javax.xml.bind.DatatypeConverter;
/**
* @author admin
*/
public class JWTUtils {
//解析token的秘钥
public static String password = "admin123";
/**
* 获取token
* @param u user
* @return token
*/
public static String getToken(aqjyxt_user u) {
Calendar instance = Calendar.getInstance();
//默认令牌过期时间7天
instance.add(Calendar.DATE, 7);
//把用户id保存到subject变量,也可以使用.withClaim("userId", 123)
JWTCreator.Builder builder = JWT.create();
builder.withSubject(u.getId());
return builder.withExpiresAt(instance.getTime())
.sign(Algorithm.HMAC256(password));
}
/**
* 验证token合法性 成功返回token
*/
public static DecodedJWT verify(String token){
return JWT.require(Algorithm.HMAC256(password)).build().verify(token);
}
/**
* 解析Jwt字符串
*
* @param jwt Jwt字符串
* @return Claims 解析后的对象
*/
public static String parseJWT(String token) {
return JWT.require(Algorithm.HMAC256(password)).build().verify(token).getClaim("userId").asString();
}
}
DecodedJWT jwt = JWT.decode(request.getHeader("token"));
System.out.println(jwt.getSubject()+"----------");
以上代码是JWT解析获取用户ID
编写JWT拦截器和JWT过滤器
package com.aqjyxt.Interceptor;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.aqjyxt.bean.JWTUtils;
import com.aqjyxt.bean.Returnben;
import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JWTInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Returnben returnben = new Returnben();
//获取请求头中的令牌
String token = request.getHeader("token");
try {
//验证令牌
DecodedJWT verify = JWTUtils.verify(token);
return true;
} catch (SignatureVerificationException e){
e.printStackTrace();
returnben.setMsg("无效签名");
returnben.setSuccess("10001");
} catch (TokenExpiredException e){
e.printStackTrace();
returnben.setMsg("token过期");
returnben.setSuccess("10002");
} catch (AlgorithmMismatchException e){
e.printStackTrace();
//token算法不一致
returnben.setMsg("无效签名");
returnben.setSuccess("10001");
} catch (Exception e){
e.printStackTrace();
returnben.setMsg("token无效");
returnben.setSuccess("10003");
}
//将map转为json
String json = new ObjectMapper().writeValueAsString(returnben);
response.setContentType("application/json;charset=UTF-8");
response.getWriter().println(json);
return false;
}
}
package com.aqjyxt.Interceptor;
import java.util.ArrayList;
import java.util.List;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* 注册拦截器
*/
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
//下面list是放行swagger
List l=new ArrayList();
l.add("/login");
l.add("/logout");
l.add("/css/**");
l.add("/js/**");
l.add("/index.html");
l.add("favicon.ico");
l.add("/doc.html");
l.add("/webjars/**");
l.add("/swagger-resources/**");
l.add("/v2/api-docs/**");
registry.addInterceptor(new JWTInterceptor())
//拦截 把需要拦截的请求配置
.addPathPatterns("/systempc/*")
//放行
.excludePathPatterns("/user/login")
.excludePathPatterns(l);
}
}
登录返回token
package com.aqjyxt.entity;
public class aqjyxt_user {
private String id;
private String user;
private String password;
private String username;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id == null ? null : id.trim();
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user == null ? null : user.trim();
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password == null ? null : password.trim();
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username == null ? null : username.trim();
}
}
@RequestMapping(value="/login",method = RequestMethod.POST)
@ResponseBody
@ApiOperation("登录接口")
public Returnben login(HttpServletRequest request, HttpSession session,aqjyxt_user aqjyxt_user) {
Returnben returnben = new Returnben();
String token = JWTUtils.getToken(aqjyxt_user);
returnben.setData(token);
returnben.setMsg("成功");
returnben.setSuccess("0");
return returnben;
}