接口权限控制(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);
        }
    }

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Spring Boot提供了多种方式实现权限控制,以下是其中几种常用的方式: 1. 基于注解的权限控制 通过在Controller方法上添加注解,可以限制用户访问该方法的权限。常用的注解包括: - @PreAuthorize:在方法执行前进行权限验证; - @PostAuthorize:在方法执行后进行权限验证; - @Secured:限制用户必须具有指定的角色才能访问该方法。 例如: ``` @PreAuthorize("hasRole('ROLE_ADMIN')") @RequestMapping("/admin") public String adminPage() { return "admin"; } ``` 2. 基于Filter的权限控制 通过自定义Filter来实现权限控制,可以在请求到达Controller之前进行权限验证,从而提高系统安全性。可以通过继承AbstractAuthenticationProcessingFilter类或实现Filter接口来实现自定义Filter。 例如: ``` public class MyFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; // 获取用户信息 String token = httpRequest.getHeader("Authorization"); if (token == null || !token.startsWith("Bearer ")) { httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized"); return; } String username = getUsernameFromToken(token.substring(7)); // 验证用户是否有权限访问该资源 if (!hasPermission(username, httpRequest.getRequestURI())) { httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN, "Forbidden"); return; } chain.doFilter(request, response); } // 判断用户是否有权限访问该资源 private boolean hasPermission(String username, String uri) { // 根据用户名和URI从数据库中获取用户权限信息 // 判断用户是否有权限访问该资源 return true; } } ``` 3. 基于Spring Security的权限控制 Spring Security是一个基于Spring的安全框架,提供了一些基本的安全功能,如用户认证、授权、会话管理等。通过配置Spring Security,可以实现基于角色的访问控制、基于URL的访问控制、CSRF攻击防护等。 例如: ``` @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/admin/**").hasRole("ADMIN") .antMatchers("/user/**").hasAnyRole("USER", "ADMIN") .anyRequest().authenticated() .and() .formLogin().loginPage("/login").permitAll() .and() .logout().permitAll(); } @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } } ``` 以上是三种常用的Spring Boot权限控制方式,根据实际需求选择合适的方式来实现权限控制

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

☆叙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值