当前端和后端分离开始时,用户权限是通过的session保存。前后端分离后,需要媒体来识别用户的状态token。JWT技术主要封装了用于用户登录鉴权的基本功能
Session:在计算机中,尤其是在网络应用中,被称为会话控制。Session对象存储特定用户会话所需的属性和配置信息。这样,当用户在应用程序中时Web当页面跳转时,存储在页面之间Session对象中的变量不会丢失,而是存在于整个用户会话中。当用户要求应用程序时 Web如果用户没有在页面上交谈,Web服务器将自动创建 Session对象。服务器将在会话过期或放弃后终止会话。Session 对象最常见的用法之一是存储用户的首选。例如,如果用户表示不喜欢查看图形,则可以存储信息Session对象中。有关使用Session 详情请参考对象ASP管理会话部分的应用程序。注意会话状态只是支持cookie保留在浏览器中。
Token在计算机身份认证中机身份认证中的含义,在词法分析中标记。一般用作邀请和登录系统。
如果非分布式一般保存在本地整体变量集中,或保存在redis中间。分布式只能保存到redis,否则,其他服务将无法获得。
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) 业务操作一般可以存储用户的基本信息。
从spring boot到spring cloud(二)JAVA入门教学,构建基础springboot_lzy711的博客-CSDN博客
查看过去的文章。
maven文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.5.7</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.aqjyxt</groupId> <artifactId>aqjyxt</artifactId> <version>0.0.1-SNAPSHOT</version> <name>aqjyxt</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.2</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-boot-starter</artifactId> <version>3.0.0</version> </dependency> <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>swagger-bootstrap-ui</artifactId> <version>1.9.6</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.4.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
主要是导入JWT
&nbp; <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.4.0</version> </dependency>
编写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
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<String> l=new ArrayList<String>();
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;
}