怎么实现对登录用户访问权限的拦截
一. 自定义权限注解
package io.coderyeah.basic.annotation;import java.lang.annotation.*;
@Target({ElementType.METHOD, ElementType.TYPE})
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface PreAuthorize {String name();String sn();
}
二. 在接口方法上使用注解
@PreAuthorize(name = "部门列表", sn = "department:list")
@LogAnnotation(module = "部门模块", operate = "分页查询部门列表")
@ApiOperation("查询部门列表")
@PostMapping("/list")
public Result list(@RequestBody(required = false) DeptDTO deptDTO) {return departmentService.list(deptDTO);
}
三. 登录拦截器
package io.coderyeah.basic.interceptor;import com.alibaba.fastjson.JSON;
import io.coderyeah.basic.annotation.PreAuthorize;
import io.coderyeah.basic.constant.Constants;
import io.coderyeah.org.mapper.EmployeeMapper;
import io.coderyeah.user.domain.LoginInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.List;
import java.util.concurrent.TimeUnit;@Component
public class LoginInterceptor implements HandlerInterceptor {@Autowiredprivate StringRedisTemplate stringRedisTemplate;@Autowiredprivate EmployeeMapper employeeMapper;@Overridepublic boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception {if (!(handler instanceof HandlerMethod)) {return true;}String token = req.getHeader("token");if (token != null) {String loginInfo = stringRedisTemplate.opsForValue().get(Constants.LOGIN_TOKEN + token); if (loginInfo != null) {stringRedisTemplate.opsForValue().set(Constants.LOGIN_TOKEN + token, loginInfo, 30, TimeUnit.MINUTES);final LoginInfo info = JSON.parseObject(loginInfo, LoginInfo.class);if (info.getType() == 1) {return true;}final HandlerMethod handlerMethod = (HandlerMethod) handler;final PreAuthorize p = handlerMethod.getMethodAnnotation(PreAuthorize.class);if (null == p) {return true;}final String sn = p.sn();List<String> ownPermissions = employeeMapper.getPermissionSnByLoginInfoId(info.getId());if (ownPermissions.contains(sn)) {return true;}resp.setCharacterEncoding("UTF-8");resp.setContentType("application/json;charset=utf-8");final PrintWriter writer = resp.getWriter();writer.print("{\"success\":false,\"message\":\"noPermission\"}");writer.close();return false;}}resp.setContentType("application/json;charset=UTF-8");resp.getWriter().println("{\"success\":false,\"message\":\"noLogin\"}");return false;}
}
四. 查询当前登录用户的所有权限涉及到多张表
<select id="getPermissionSnByLoginInfoId" resultType="java.lang.String">select tp.snfrom t_employee tejoin t_employee_role ter on te.id = ter.employee_idjoin t_role tr on ter.role_id = tr.idjoin t_role_permission trp on tr.id = trp.role_idjoin t_permission tp on tp.id = trp.permission_idwhere te.logininfo_id = #{id}
</select>
![网络传输数据安全](https://img-blog.csdnimg.cn/img_convert/964d8afa1e94cdf2af60d98ccfac409d.png)
五. 前端后置拦截器处理
axios.interceptors.response.use(res => {if (false === res.data.success && "noLogin" === res.data.message) {localStorage.removeItem("token");localStorage.removeItem("loginInfo");router.push({path: '/login'});}if (false === res.data.success && "noPermission" === res.data.message) {Message.info('您没有访问权限')}return res;
},error => {Promise.reject(error)
})
info('您没有访问权限')}return res;
},error => {Promise.reject(error)
})