框架建设收集

十三 . 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';
    }
}
上一篇下一篇

猜你喜欢

热点阅读