十三 . token权限检测 - Aspectj
2019-10-11 本文已影响0人
任未然
一 . 概述
在实际业务中, 有些访问后台的场景需要用户登录权限, 本文将介绍token令牌权限访问后台, 主要使用技术为: spring-aop
二. 使用
2.1 导包
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.3</version>
</dependency>
</dependencies>
2.2 编写自定义注解: TokenPermit
@Target({ElementType.METHOD}) //作用的位置
@Retention(RetentionPolicy.RUNTIME) //作用域
public @interface TokenPermit {
PermitType value();
}
说明: 该注解用于声明那些方法需要走权限过滤
2.3 编写枚举类: PermitType
public enum PermitType {
// authentication 认证
// anonymous 匿名
auth, anonymous
}
说明: 该枚举配合注解使用
2.4 编写权限过滤类: TokenAuthAdvisor
说明: 有@TokenPermit注解的方法在执行之前都会先执行该类的round()方法
@Aspect
@Component
public class TokenAuthAdvisor {
/**
* springmvc中转json, json转对象
*/
@Autowired
private ObjectMapper objectMapper; //
/**
* 检测到方法头顶上有@TokenPermit, 该通知就会执行
*/
@Around("@annotation(com.qf.commons.TokenPermit)")
public Object round(ProceedingJoinPoint pjp) throws Throwable {
MethodSignature methodSignature = (MethodSignature) pjp.getSignature(); //获取方法的签名
Method method = methodSignature.getMethod(); //获取Method对象
TokenPermit tokenPermit = method.getAnnotation(TokenPermit.class); // 获取TokenPermit注解
PermitType permitType = tokenPermit.value(); //获取注解类型
Object obj = null;
if (permitType.equals(PermitType.anonymous)) { //如果定义是匿名方式
obj = pjp.proceed();
} else { // 获取请求头中是否有token
// 获取Request对象
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
String token = request.getHeader("token");
if (null == token || "".equals(token)) {
Map<String, Object> map = new HashMap<>();
map.put("code", -2);
map.put("message", "未经授权.");
response.setContentType("application/json;charset=utf-8");
response.setStatus(HttpStatus.FORBIDDEN.value()); // 403
response.getWriter().write(objectMapper.writeValueAsString(map));
} else {
System.out.println("授权通过=======================");
obj = pjp.proceed();
System.out.println("obj: " + obj);
}
}
return obj;
}
}
2.5 编写登录类: login
说明: 登录后成功后,生成一个token令牌给前端, 前端把token储存到cookies中,再次访问后台时,请求头携带token参数
@RequestMapping("/login")
@RestController
public class LoginController {
@TokenPermit(PermitType.anonymous)
@RequestMapping
public Object login(String username, String password) {
System.out.println("username: " + username + ";; password: " + password);
Map<String, Object> map = new HashMap<>();
// token
map.put("token", UUID.randomUUID());//随机生成token令牌
map.put("code", 1);
return map;
}
}
2.6 controller层
@RestController
@RequestMapping("/user")
@CrossOrigin(origins = "*")
public class UserController {
@TokenPermit(PermitType.auth)
@RequestMapping
public Object hello {
return 'hello';
}
}