前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SaaS-基于JWT的API鉴权

SaaS-基于JWT的API鉴权

作者头像
cwl_java
发布2020-01-02 11:48:26
1.1K0
发布2020-01-02 11:48:26
举报
文章被收录于专栏:cwl_Java

3 基于JWT的API鉴权

3.1 基于拦截器的token与鉴权

如果我们每个方法都去写一段代码,冗余度太高,不利于维护,那如何做使我们的代码看起来更清爽呢?我们可以将这段代码放入拦截器去实现

3.1.1 Spring中的拦截器

Spring为我们提供了org.springframework.web.servlet.handler.HandlerInterceptorAdapter这个适配器,继承此类,可以非常方便的实现自己的拦截器。他有三个方法:分别实现预处理、后处理(调用了Service并返回ModelAndView,但未进行页面渲染)、返回处理(已经渲染了页面)

  1. 在preHandle中,可以进行编码、安全控制等处理;
  2. 在postHandle中,有机会修改ModelAndView;
  3. 在afterCompletion中,可以根据ex是否为null判断是否发生了异常,进行日志记录。

3.2 签发用户API权限

在系统微服务的 com.ihrm.system.controller.UserController 修改签发token的登录服务添加API权限

代码语言:javascript
复制
/**
     * 用户登录
     * 1.通过service根据mobile查询用户
     * 2.比较password
     * 3.生成jwt信息
     *
     */
    @RequestMapping(value="/login",method = RequestMethod.POST)
    public Result login(@RequestBody Map<String,String> loginMap) {
        String mobile = loginMap.get("mobile");
        String password = loginMap.get("password");
        User user = userService.findByMobile(mobile);
        //登录失败
        if(user == null || !user.getPassword().equals(password)) {
            return new Result(ResultCode.MOBILEORPASSWORDERROR);
       }else {
            //登录成功
            //api权限字符串
            StringBuilder sb = new StringBuilder();
            //获取到所有的可访问API权限
            for (Role role : user.getRoles()) {
                for (Permission perm : role.getPermissions()) {
                    if(perm.getType() == PermissionConstants.PERMISSION_API) {
                        sb.append(perm.getCode()).append(",");
                   }
               }
           }
            Map<String,Object> map = new HashMap<>();
            map.put("apis",sb.toString());//可访问的api权限字符串
            map.put("companyId",user.getCompanyId());
            map.put("companyName",user.getCompanyName());
            String token = jwtUtils.createJwt(user.getId(), user.getUsername(), map);
            return new Result(ResultCode.SUCCESS,token);
       }
   }

3.3 拦截器中鉴权

(1)在ihrm-common下添加拦截器 JwtInterceptor

代码语言:javascript
复制
@Component
public class JwtInterceptor extends HandlerInterceptorAdapter {
    @Autowired    
    private JwtUtil jwtUtil;    
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 
Object handler) throws Exception {
        // 1.通过request获取请求token信息
        String authorization = request.getHeader("Authorization");
        //判断请求头信息是否为空,或者是否已Bearer开头
        if(!StringUtils.isEmpty(authorization) && authorization.startsWith("Bearer")) {
            //获取token数据
            String token = authorization.replace("Bearer ","");
            //解析token获取claims
            Claims claims = jwtUtils.parseJwt(token);
            if(claims != null) {
                //通过claims获取到当前用户的可访问API权限字符串
                String apis = (String) claims.get("apis");  //api-user-delete,api-userupdate
                 //通过handler
                HandlerMethod h = (HandlerMethod) handler;
                //获取接口上的reqeustmapping注解
                RequestMapping annotation = h.getMethodAnnotation(RequestMapping.class);
                //获取当前请求接口中的name属性
                String name = annotation.name();
                //判断当前用户是否具有响应的请求权限
                if(apis.contains(name)) {
                    request.setAttribute("user_claims",claims);
                    return true;
               }else {
                    throw new CommonException(ResultCode.UNAUTHORISE);
               }
           }
       }
        throw new CommonException(ResultCode.UNAUTHENTICATED);
   }
}

(2)修改UserController的profile方法

代码语言:javascript
复制
/**
     * 用户登录成功之后,获取用户信息
     *     1.获取用户id
     *     2.根据用户id查询用户
     *     3.构建返回值对象
     *     4.响应
     */
    @RequestMapping(value="/profile",method = RequestMethod.POST)
    public Result profile(HttpServletRequest request) throws Exception {
        String userid = claims.getId();
        //获取用户信息
        User user = userService.findById(userid);
        //根据不同的用户级别获取用户权限
        ProfileResult result = null;
        if("user".equals(user.getLevel())) {
            result = new ProfileResult(user);
       }else {
            Map map = new HashMap();
            if("coAdmin".equals(user.getLevel())) {
                map.put("enVisible","1");
           }
            List<Permission> list = permissionService.findAll(map);
            result = new ProfileResult(user,list);
       }
        return new Result(ResultCode.SUCCESS,result);
   }

(3)配置拦截器类,创建com.ihrm.system.SystemConfig

代码语言:javascript
复制
@Configuration
public class SystemConfig extends WebMvcConfigurationSupport {
    @Autowired
    private JwtInterceptor jwtInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(jwtInterceptor).
        addPathPatterns("/**").
        excludePathPatterns("/frame/login","/frame/register/**"); //设置不拦截的请求地址
   }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 3 基于JWT的API鉴权
    • 3.1 基于拦截器的token与鉴权
      • 3.1.1 Spring中的拦截器
    • 3.2 签发用户API权限
      • 3.3 拦截器中鉴权
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档