第三課:springboot+自定義注解做接口的權限校驗
- 簡介
- 項目的目錄
- 項目的代碼内容
-
- 1.自定義的注解内容
- 2.自定義的攔截器
- 3. 自定義controller
- 項目的執行流程
簡介
項目中經常能碰到有些接口是需要使用者登入之後才能通路的,而有些的是不要做登入校驗的;
當然可以使用到一些權限管理的架構;但是有些簡單的業務功能的就可以通過自定義注解+自定義的攔截器設定指定的消息内容;
項目demo下載下傳
項目的目錄
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIwczX0xiRGZkRGZ0Xy9GbvNGL2EzXlpXazxSP9cWT5VlaNh3Z61EM4wmYwhGWhxGZzwEMW1mY1RzRapnTtxkb5ckYplTeMZTTINGMShUYfRHelRHLwEzX39GZhh2css2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xyayFWbyVGdhd3LcV2Zh1Wa9M3clN2byBXLzN3btg3Pn5GcuQzM2QDN1QTM1EDMxkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
項目的代碼内容
1.自定義的注解内容
主要通過添加在指定的方法判斷接口通路是不是需要登入
/***
* 設定攔截器通過注解設定某種屬性
* @author kanghanyu
* 自定義的注解内容設定對應的内容資訊
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AuthPassport {
/**
* 是否需要登入
* @return
*/
boolean auth() default false;
}
2.自定義的攔截器
/**
* 自定義攔截器的 通過擷取請求接口自定義的注解判定是否需要登入傳回對應的資訊
* @author khy
* @createTime 2019年10月9日上午11:37:02
*/
@Configuration
public class AnnotationInterceptor extends WebMvcConfigurerAdapter {
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new HandlerInterceptorAdapter() {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// 驗證使用者權限
if (handler.getClass().isAssignableFrom(HandlerMethod.class)) {
AuthPassport authPassport = ((HandlerMethod) handler).getMethodAnnotation(AuthPassport.class);
if (authPassport != null) {
boolean auth = authPassport.auth();
//如果是需要登入校驗的
if(auth){
String userName = AnnotationController.userName;
String password = AnnotationController.password;
if(StringUtils.isAnyBlank(userName,password)){
auth = false;
}
if(!userName.equals(password) || !userName.equals(AnnotationController.LOGIN_FLAG)){
auth = false;
}
if(!auth){
JSONObject json = new JSONObject();
json.put("code", "10000");
json.put("msg", "使用者未登入不能通路");
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(JSON.toJSONString(json));
return false;
}
}
}
}
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
Exception ex) throws Exception {
if (ex != null) {
Enumeration<String> enu = request.getParameterNames();
Map<String, Object> param = new HashMap<String, Object>();
while (enu.hasMoreElements()) {
String paraName = (String) enu.nextElement();
param.put(paraName, request.getParameter(paraName));
}
} else {
super.afterCompletion(request, response, handler, ex);
}
}
@Override
public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
super.afterConcurrentHandlingStarted(request, response, handler);
}
}).addPathPatterns("/annotation/**");//攔截的請求路徑位址内容
}
}
3. 自定義controller
@RestController
@RequestMapping("/annotation")
public class AnnotationController {
private static final Logger khy = LoggerFactory.getLogger("KHY");
public static final String LOGIN_FLAG = "admin";
public static String userName = "test";
public static String password = "test";
/**
* 這個是模拟登入的接口内容
* http://localhost:8080/annotation/login?userName=admin&password=admin
* @param userName
* @param password
* @return
*/
@RequestMapping("/login")
public String login(String userName,String password){
if(StringUtils.isNotBlank(userName)){
this.userName = userName;
}
if(StringUtils.isNotBlank(password)){
this.password = password;
}
return "登入成功";
}
/**
* 這個是模拟儲存需要登入
* http://localhost:8080/annotation/save?userName=admin&password=admin
* @param userName
* @param password
* @return
*/
@AuthPassport(auth=true)
@RequestMapping("/save")
public String save(String userName,String password){
khy.debug("儲存使用者userName={},password={}",userName,password);
return "登入成功";
}
/**
* 這個是模拟查詢接口不需要登入
* http://localhost:8080/annotation/query?userName=admin&password=admin
* @param userName
* @param password
* @return
*/
@AuthPassport(auth=false)
@RequestMapping("/query")
public String query(String userName,String password){
khy.debug("查詢使用者userName={},password={}",userName,password);
return "查詢成功";
}
項目的執行流程
首先AnnotationController 裡面的三個方法
1.login方法沒有自定義的注解@AuthPassport
是以請求http://localhost:8080/annotation/login 接口會被AnnotationInterceptor攔截器攔截但是不符合注解條件直接進入接口執行.
2.query 方法上面雖然有指定的 @AuthPassport 但是裡面的auth=false
在攔截器裡面執行但是也不去校驗登入的資訊内容;是以在不調用login 的接口之前也可以通過 http://localhost:8080/annotation/query 直接調用此接口
3.save 方法上有指定的@AuthPassport 注解并且auth=true 辨別需要登入之後才能通路;如果項目啟動就直接調用http://localhost:8080/annotation/save 會因為在AnnotationInterceptor 攔截器裡面的去比對校驗的資訊内容.
總結:項目中的登入接口隻是用來模拟使用的;真正的項目中校驗的登入的資訊是在AnnotationInterceptor 攔截器裡面根據使用者的資訊去擷取使用者是否有對應的接口通路權限然後再判斷是否去調用指定的接口.