目前市面上有许多鉴权框架,鉴权原理大同小异,本文简单介绍下利用JWT和Redis实现鉴权功能,算是抛砖引玉吧。
主要原理就是“令牌主动失效机制”,主要包括以下4个步骤:
(1)利用拦截器LoginInterceptor实现所有接口登录拦截(其中登录接口和注册接口不拦截)
(2)登录成功后,利用JWT生成包含有效期的Token令牌,在给浏览器响应令牌的同时,将该令牌存储到Redis中。
(3)在LoginInterceptor拦截器中,需要验证浏览器携带的Token,与Redis中存储的Token对比,不一致则报错,否则,继续。
(4)当用户修改密码成功后,删除Redis中存储的旧令牌。
一、代码实战
1、环境准备
application.yaml配置
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/big_event
username: root
password: root1234
data:
redis:
host: localhost
port: 6379
mybatis:
configuration:
map-underscore-to-camel-case: true #开启驼峰命名和下划线命名的自动转换;这里是全局配置,也可以在mapper接口中单独配置
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
server:
port: 8080
pom.xml核心配置
<!--mybatis依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
<!--java-jwt坐标-->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>4.4.0</version>
</dependency>
<!--redis坐标-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2、LoginInterceptor拦截器
@Component
public class LoginInterceptor implements HandlerInterceptor {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//令牌验证
String token = request.getHeader("Authorization");
//验证token
try {
//从redis中获取相同的token
ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
String redisToken = operations.get(token);
if (redisToken == null) {
//token已经失效了
throw new RuntimeException();
}
Map<String, Object> claims = JwtUtil.parseToken(token);
//把业务数据存储到ThreadLocal中
ThreadLocalUtil.set(claims);
//放行
return true;
} catch