美文网首页猴子也能懂的springboot教程
猴子也能懂的springboot教程(四) - springbo

猴子也能懂的springboot教程(四) - springbo

作者: 程序员的幻想乡 | 来源:发表于2019-05-18 16:35 被阅读0次
    illust_72693620_20190518_163138.png

    摘要

    本文介绍springboot使用拦截器,实现用户登录权限管理

    前言

    本demo实现功能:
    判断用户是否否登录

    1. 在拦截器中验证请求是否带token,若带token,验证是否在缓存中存在,存在说明已登录,允许请求资源;不存在,则重定向到无权限提示
    2. 请求完资源后,重置缓存中token过期时间

    思路拓展:若需要更细层次的权限管理,可在缓存的对象中存储该用户可访问的资源列表,查看本次请求是否在列表内,是则允许,不是则无权限。

    本次项目需要使用Redis作为缓存,故承接篇文章
    猴子也能懂的springboot教程(三) - springboot整合Redis
    废话不说,开始

    创建Controller

    本文承接以前文章,故存在TestController,直接修改即可,读者可自行创建。
    实现三个功能:登录,根据id查询信息,无权限重定向接口

    @RestController
    @RequestMapping("test")
    public class TestController {
    
        @Autowired
        private IUserService userService;
        // 简单登录
        @GetMapping("login/{name}")
        public String login(@PathVariable String name){
            User user = userService.getUserByUsername(name);
            return "hi " + user.getUsername() + " your" +
                    "<br/> id is "+ user.getId() +
                    "<br/> token is "+ user.getToken();
        }
        // 根据ID查询
        @GetMapping("id/{id}")
        public String getUserById(@PathVariable String id){
            User user = userService.getUserById(id);
            return "hi " + user.getId() + " your name is "+ user.getUsername();
        }
        // 无权限
        @GetMapping("/noAuthority")
        public String noAuthority(){
            return "you have no Authority";
        }
    }
    

    创建拦截器

    创建com.gao.interceptor.AuthorityInterceptor实现==HandlerInterceptor==接口
    实现功能:

    preHandle 实现:

    1. 获取token
    2. 在缓存中查token是否存在
    3. 若存在,处理权限逻辑(未实现,本文只验证是否登录)
    4. 不存在,跳转无权限接口

    afterCompletion 实现:

    1. 重置token过期时间
    package com.gao.interceptor;
    @Component
    public class AuthorityInterceptor implements HandlerInterceptor{
    
        private Logger logger = LogManager.getLogger(this.getClass());
    
        @Value("${spring.redis.cache.user.key}")
        private String userCacheKey;
    
        @Autowired
        ICache cache;
    
        @Override
        public boolean preHandle(HttpServletRequest request, 
        HttpServletResponse response, 
        Object handler) throws Exception {
        
            logger.warn("AuthorityInterceptor拦截器 pre");
            String token = request.getParameter("token");
            if(!StringUtils.isEmpty(token)){
                Object o = cache.get(userCacheKey + token);
                if(null != o){
                    logger.warn("有权限");
                    return true;
                }
            }
            logger.warn("无权限");
            response.sendRedirect("/test/noAuthority");
            return false;
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request,
        HttpServletResponse response, 
        Object handler,
        @Nullable Exception ex) throws Exception {
        
            logger.warn("AuthorityInterceptor拦截器 after");
            String token = request.getParameter("token");
            if(!StringUtils.isEmpty(token)){
                //重置token过期时间
                cache.expireHalfHour(userCacheKey+token);
            }
        }
    }
    

    配置拦截器

    创建com.gao.config.WebMvcConfig实现==WebMvcConfigurer==接口

    @Configuration
    public class WebMvcConfig implements WebMvcConfigurer{
    
        @Autowired
        private AuthorityInterceptor authorityInterceptor;
    
        @Override
        public void addInterceptors(InterceptorRegistry registry){
            InterceptorRegistration interceptorRegistration =
                           registry.addInterceptor(authorityInterceptor);
            //拦截
            interceptorRegistration.addPathPatterns("/test/**");
            //放开
            interceptorRegistration.excludePathPatterns("/test/login/**");
            interceptorRegistration.excludePathPatterns("/test/noAuthority");
        }
    
    }
    

    此时,一个简单的登录权限的拦截器就实现了,下面开始测试

    测试

    1. 启动服务器,输入 IP:端口/test/id/8f5689836eef11e9869d000d29242eff 页面被重定向到 IP:端口/test/noAuthority


      20190514180002.png
    1. 输入 IP:端口/login/stephen


      20190514180001.png
    1. 输入 IP:端口/test/id/8f5689836eef11e9869d000d29242eff?token=32fe990d-efe5-4b9e-b310-2bbef999946d 此处token是上面返回的


      20190514180003.png

    未登录的信息已经被拦截。此时去Redis查看,该token过期时间也被重置了。
    至此,一个简单的拦截器功能实现了。

    系列文章

    猴子也能懂的springboot教程

    相关文章

      网友评论

        本文标题:猴子也能懂的springboot教程(四) - springbo

        本文链接:https://www.haomeiwen.com/subject/hdmtzqtx.html