The functional requirements

Encountered a problem, to achieve permission management, that is, some button click to prompt, no permission, there are many interfaces, if according to the old way, is each method handwritten permission judgment. It’s a waste of time

The important point of the question

  1. Repetitive work, how to solve
  2. The project does not introduce shiro module and the session is stored in Redis, so distributed environment can also use the session, how to obtain user information from the session

Not much. How do YOU do it

  1. Aop is used to implement repeated permission judgment
  2. The session can be retrieved from the RequestContextHolder class

Permission to annotate

import java.lang.annotation.*;

@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
/** ** ** **@Permission({"/admin/hasPermission","/admin/isAlive"})
 * */
public @interface Permission {
    String[] value() default {};
}
Copy the code

PermissionAop

import com.seniortech.test.annotation.Permission;
import com.seniortech.test.entity.Admin;
import com.seniortech.test.response.LayData;
import com.seniortech.test.service.PermissionService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.aspectj.lang.reflect.MethodSignature;
import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;
import java.util.Objects;

/ * * *@author husky
 * @date2019/6/24 17:46 * /
@Aspect
@Configuration
public class PermissionAop {
    @Resource
    private PermissionService permissionService;

    // Define Pointcut Pointcut
    @Pointcut(value="@annotation(com.seniortech.test.annotation.Permission)")
    public void excudeService(a){}@Around("excudeService()")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        HttpSession session = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest().getSession();
        Admin admin =(Admin) session.getAttribute("admin");// The above two lines can retrieve request, i.e. session
        if(! Objects.isNull(admin)){ System.out.println(admin); MethodSignature ms = (MethodSignature) proceedingJoinPoint.getSignature(); Method method = ms.getMethod(); Permission permission = ((Method) method).getAnnotation(Permission.class); String[] permissions = permission.value();// Here you can get an annotation in @Permission, an array of strings
            Permissions = 0; permissions = 0
            if(! permissionService.hasPermission(admin.getId(),permissions)){return LayData.builder().code(-1).msg("No access").build();
            }
            // LayData here is the uniform format of response
        }
        Object result = proceedingJoinPoint.proceed();
        returnresult; }}Copy the code

Wrapper code at the front-end Ajax

/** * Ajax encapsulation * URL sends the request to the address * data sent to the server, array storage, such as: {"date":new date ().getTime(),"state":1} * SuccessFn Success callback * errorFn Failure callback * */
            jQuery.postAjax = function (url,data,successfn,errorfn) {
                data = (data === null || data === "" 
                        || typeof (data) === "undefined")
                        ?{"date":new Date().getTime()}:data;
                var loadObj = layer.load(2);
                $.ajax({
                    type: "post".data: data,
                    url: url,
                    success: function (d,textStatus,jqXHR) {
                        layer.close(loadObj);
                        if(d.code === - 100.) {// The login status is invalid
                            layer.confirm("Login is invalid. Please log in again.",
                                    {icon:2.title: 'tip'.btn: ['sure'].closeBtn:0},function (index) {
                                        window.location.href = "/login.html";
                                    })
                            return;
                        }
                        if(d.code === - 1) {// No operation or permission is forbidden
                            console.log("No access");
                            layer.msg(d.msg,{icon:0});
                            return;
                        }
                        successfn(d);
                    },
                    error:function (e) {
                        layer.close(loadObj);
                        if(errorfn ! = =undefined){ errorfn(e); }}})}Copy the code

Back-end call code

@Permission("/admin/disable")
    @RequestMapping("/disable")
    @ResponseBody
    public Object administratorDisable(Integer userId){
        Integer returnCode = adminService.setStatus(Admin.builder().id(userId.longValue()).status(false).build());
        if(returnCode == 0) {return LayData.builder().code(400).build();
        }else{
            return LayData.builder().code(200).build(); }}Copy the code

I would be more sympathetic to the idea that laziness is a ladder of human progress.

The first thing THAT comes to mind when I find myself doing something repetitive is that there is a very good way to simplify it

Here, I thank guns for the open source framework that inspired me to implement AOP using annotations

Aop to get the Request annotation used with AOP, from guns source