一,使用场景
1.登录校验
2.信息加密
导入jar
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
二,代码实现(AOP+自定义注解+JWT)代码实现登录校验
自定义注解
package com.xy.login;
import java.lang.annotation.*;
/**
* @Target - 当前注解的作用范围
* ElementType.CONSTRUCTOR - 能够标注在构造方法上
* ElementType.FIELD - 能够标注在属性(全局变量)上
* ElementType.LOCAL_VARIABLE - 能够标注在局部变量上
* ElementType.METHOD - 方法上
* ElementType.PARAMETER - 方法形参
* ElementType.TYPE - 类、接口、内部类
*
* @Retention - 当前注解的有效范围
* RetentionPolicy.SOURCE - 表示当前注解在源码中有效,一旦编译成class文件,注解会丢失
* RetentionPolicy.CLASS - 表示当前注解在源码、class文件中有效,一旦运行时,就会丢失
* RetentionPolicy.RUNTIME - 表示当前注解运行时有效,如果需要配合反射使用,必须是Runtime范围
*
* 方法语法: 返回值类型 方法名() [default 默认值];
*/
@Documented
@Inherited
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface IsLogin {
boolean mustLogin() default false;
}
AOP
package com.xy.login;
import com.xy.entity.ResultData;
import com.xy.entity.User;
import com.xy.tool.JwtUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
/**
* 切面类
*
* 前置
* 后置
* 环绕
* 异常
* 后置完成
*
*/
@Aspect
@Component
public class LoginAop {
/**
* 环绕增强
* @param joinPoint
* @return
*/
@Around("@annotation(IsLogin)")
public Object isLogin(ProceedingJoinPoint joinPoint){
//前置增强
//通过请求获得jwtToken和devId
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = requestAttributes.getRequest();
//通过参数获取jwtToken和devId
String jwtToken = request.getParameter("jwtToken");
String devId = request.getParameter("devId");
User user = null;
//判断
if(jwtToken != null && devId != null){
//有可能登录
user = JwtUtil.isToken(jwtToken, devId);
}
if(user == null){
//说明未登录
//获取方法上的IsLogin注解,判断mustLogin方法的返回值
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
IsLogin isLogin = method.getAnnotation(IsLogin.class);
boolean flag = isLogin.mustLogin();
if (flag){
//强制登录
//通知前端
return new ResultData().setCode(ResultData.Code.TOLOGIN);
}
}
//设置登录的用户信息 使用
UserUtil.setUser(user);
Object result = null;
try {
//目标方法的调用
result = joinPoint.proceed();
//后置增强
} catch (Throwable throwable) {
throwable.printStackTrace();
//异常增强
} finally {
//后置完成增强
}
return result;
}
}
JwtUtil
package com.xy.tool;
import com.qf.entity.User;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
public class JwtUtil {
/**
* 密钥
*/
private static final String secrt = "21laksdfiua42131giuwgelkwqjrlkjhadklsf";
/**
* 密钥1天过期
*/
private static final Integer timeout = 1000 * 60 * 60 * 24;
/**
* 生成JWT的令牌
* @return
*/
public static String createJwtToken(User user, String devId){
JwtBuilder builder = Jwts.builder()
.setId(user.getId() + "")
.setSubject(user.getNickname())
.setIssuedAt(new Date())
//添加自定义属性
.claim("uid", user.getId())
.claim("username", user.getUsername())
//设置jwt的过期时间
.setExpiration(new Date(System.currentTimeMillis() + timeout))
.signWith(SignatureAlgorithm.HS256,secrt + devId);
String jwtToken = builder.compact();
return jwtToken;
}
/**
* 验签token的方法
*/
public static User isToken(String jwtToken, String devId){
try {
Claims claim = Jwts.parser().setSigningKey(secrt + devId)
.parseClaimsJws(jwtToken).getBody();
System.out.println("验签通过");
//解析出用户的自定义信息
Integer uid = (Integer) claim.get("uid");
String username = (String) claim.get("username");
User user = new User().setId(uid).setUsername(username);
return user;
} catch (Exception e) {
System.out.println("验签未通过!");
}
return null;
}
}
ThreadLocal 保存用户信息
public class UserUtil {
private static ThreadLocal<User> user = new ThreadLocal<>();
public static User getUser() {
return UserUtil.user.get();
}
public static void setUser(User user) {
UserUtil.user.set(user);
}
}
先登录获取Token
String jwtToken = JwtUtil.createJwtToken(user, devId);
通过注解的方式就可以实现环绕增强。