接口权限控制(springboot)
原理:首先调用登录,会传递一个token给前端,之后的接口都需要用到这个token,需要前端将token放入请求头里面,在调接口的时候传过来,后端获取到了这个token后,将获取的token与数据库中的比对,相同则说明已登录,可以调用接口。
实现解析:
1、首先需要登录,需要生成一个token,并且token要存入数据库,token怎么存?
考虑到这个token基本不会变并且使用频繁,因此存储到redis中是一个不错的选择,后面请求头中token都与redis中的进行比对,想要在redis中找到这个token,因此需要不同的key来标识不同的token,例如token1:"12345",token2:"23456",因此需要定义一个容易找的标识,我使用的是cache_具体的token值这种格式。
2、第二个问题,在每个接口之前都写上一个获取token的方法判断吗?
这种方式肯定是不可取的,接口如果多起来了,会很麻烦,因此我用到了spring的AOP面向切面编程,就是在controller中的每个接口之前建了一个切面,在这个切面统一执行一个方法,去判断token,这样可以统一的管理,不需要去重复写代码判断,在这里我们不要忘记去过滤登录的接口,那个接口不需要token。
3、如果用户长时间未操作,为了安全考虑,token需要自动销毁,如何做呢,定时任务吗?
类似与定时任务,redis可以给里面的数据设置一个存活时间,到了时间会自动删除,但是为了用户的体验,因此需要在每次调接口的时候,刷新一遍存活时间,这样可以优化用户的体验。
主要实现代码如下:
//建立切点
@Pointcut("execution(* com.example.blog.controller.*.*(..))")public void controllerMethod(){}@Before("controllerMethod()")public void LogRequestInfo(JoinPoint joinPoint){RequestAttributes requestAttribute = RequestContextHolder.getRequestAttributes();HttpServletRequest request = ((ServletRequestAttributes)requestAttribute).getRequest();// 打印请求内容log.info("----------------------------------------------------------接口调用发起----------------------------------------------------------");log.info("接收到请求,请求方式={},请求地址={},请求IP={},请求方法名称={},请求参数={}",request.getMethod(),request.getRequestURL().toString(),ToolsUtil.getServerIp(),joinPoint.getSignature().getName(), Arrays.toString(joinPoint.getArgs()));//过滤登录接口if(!joinPoint.getSignature().getName().equals("userLogin")){//接口之前,权限校验String key = "cache_token_"+ RequestUtil.getUserId();if(ParamUtil.empty(redisUtil.get(key))){log.info("接口调用失败:返回结果=" + ResponseCode.NoAuthor.toString());log.info("----------------------------------------------------------接口调用结束----------------------------------------------------------");throw new CommonException(ResponseCode.NoAuthor.getMessage(),ResponseCode.NoAuthor.getMessage_en(),ResponseCode.NoAuthor.getErrorCode());}if(!Objects.equals(RequestUtil.getToken(), redisUtil.get(key))){log.info("接口调用失败:返回结果=" + ResponseCode.NOPOWER.toString());log.info("----------------------------------------------------------接口调用结束----------------------------------------------------------");throw new CommonException(ResponseCode.NOPOWER.getMessage(),ResponseCode.NOPOWER.getMessage_en(),ResponseCode.NOPOWER.getErrorCode());}//刷新token存活时间redisUtil.expire(key,4*60*60);}}
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
