如果你尚未了解Springboot拦截器,请先看本人之前文章:Springboot 拦截器
为了让大家更加直观的了解,下面每个步骤都是先放代码,然后放对应代码的截图。
举例:我们以删除文章为例,假设文章只允许管理员删除。
(1)首先我们创建一个注解类:OnlyAdmin
package com.zyq.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 管理员才允许的请求
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface OnlyAdmin {
}
(2)在后台对应的方法上,打上@OnlyAdmin注解
/**
* 删除博客文章
*/
@OnlyAdmin
@RequestMapping("/delete")
@ResponseBody
public Resp<String> delete(long id) {
bokeService.delete(id);
return Resp.success();
}
(3) 在登陆拦截器中拦截请求,判断当前登陆用户是否拥有该权限(下面那几个方法不用实现)。
package com.zyq.interceptor;
import java.io.PrintWriter;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import com.zyq.annotation.OnlyAdmin;
import com.zyq.beans.User;
import com.zyq.consts.SessionKey;
import com.zyq.tools.DateTool;
/**
* 登录拦截器
*/
public class LoginInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
// 从session中获取用户对象(该对象在用户登录的时候存于session中)
Object object = request.getSession().getAttribute(SessionKey.USER_OBJECT);
// 用户未登录,则以游客身份登录
if (object == null) {
User user = new User();
user.setId(-1L);
user.setName("游客" + DateTool.formatDateTimeSecond(new Date()));
request.getSession().setAttribute(SessionKey.USER_OBJECT, user);
}
// 请求的方法是否有注解
boolean haveAnnotataion = handler.getClass().isAssignableFrom(HandlerMethod.class);
if (haveAnnotataion) {
// 检测是否有 @OnlyAdmin 注解
OnlyAdmin oa = ((HandlerMethod)handler).getMethodAnnotation(OnlyAdmin.class);
if (oa != null) {
// 如果有 @OnlyAdmin则表明该方法只允许管理员删除
Object user = request.getSession().getAttribute(SessionKey.USER_OBJECT);
if (((User)user).getId().longValue() != 1L) { // 这里假设以ID为1为管理员
response.setCharacterEncoding("UTF-8");
response.setContentType("text/json;charset=utf-8");
PrintWriter pw = response.getWriter();
pw.flush();
pw.println("{\"msg\":\"你未有该权限\"}");
return false;
}
}
}
// 用户已登录,则返回true, 放行该请求
return true;
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
// TODO Auto-generated method stub
super.afterCompletion(request, response, handler, ex);
}
@Override
public void afterConcurrentHandlingStarted(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
// TODO Auto-generated method stub
super.afterConcurrentHandlingStarted(request, response, handler);
}
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
// TODO Auto-generated method stub
super.postHandle(request, response, handler, modelAndView);
}
}
(3)重启项目,不登录访问页面,然后执行删除操作。
(4)可以看到,游客并不能删除。
(5)打开F12,你也可以看到,请求也是返回的未有权限操作。
(6)现在点击退出游客模式,登陆管理员账号。
(7)登陆管理员账户。
(8)登陆后,再次点击删除。
(9)可以看到文章已被删除了
【结尾语】
(1)我们这里通过id=1来当成管理员只是为了掩饰,真实场景的时候,为了给用户设不同的权限,是在user对象中有一个权限字段(比如role=1为超级管理员,role=2为管理员,role=3为游客这样的)
(2)真正做项目的时候,如果某个用户不具备某个功能的权限,一般是不给与显示的,比如我这个游客模式下是不应该显示【删除】这个按钮的,这里显示仅为演示效果。
Springboot的自定义注解,权限管理验证,你学会了吗?
-----------------------------------------------------------------------
码字不易,且看且点赞,点赞走一走,能活九十九。
-----------------------------------------------------------------------