如果我们每个方法都去写一段代码,冗余度太高,不利于维护,那如何做使我们的代码看起来更清爽呢?我们可以将这段代码放入拦截器去实现
Spring为我们提供了org.springframework.web.servlet.handler.HandlerInterceptorAdapter这个适配器,继承此类,可以非常方便的实现自己的拦截器。他有三个方法:分别实现预处理、后处理(调用了Service并返回ModelAndView,但未进行页面渲染)、返回处理(已经渲染了页面)
在系统微服务的 com.ihrm.system.controller.UserController 修改签发token的登录服务添加API权限
/**
* 用户登录
* 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);
}
}
(1)在ihrm-common下添加拦截器 JwtInterceptor
@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方法
/**
* 用户登录成功之后,获取用户信息
* 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
@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/**"); //设置不拦截的请求地址
}
}