1. Obtain the requested device and register it

1.1 Mobile dependency added. Other Swagger and SpringBoot basic dependencies please add by yourself.

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mobile</artifactId> < version > 1.5.22. RELEASE < / version > < / dependency >Copy the code

1.2 First inject the Bean that gets the requesting device into MVC.

@Component
public class MvcConf implements WebMvcConfigurer {

    @Bean
    public DeviceHandlerMethodArgumentResolver
    deviceHandlerMethodArgumentResolver() {
        returnnew DeviceHandlerMethodArgumentResolver(); } @Override public void addArgumentResolvers( List<HandlerMethodArgumentResolver> argumentResolvers) { argumentResolvers.add(deviceHandlerMethodArgumentResolver()); }}Copy the code

2. Implement interceptors manually

2.1 Creating user entities. There is no device-related field in the designed data table, so when entities are used, they are directly added to the mapped entity class through @TRANSIENT annotation for convenience.

@Table(name="sys_user") @Data @Builder @NoArgsConstructor @AllArgsConstructor public class SysUser implements Serializable { private static final long serialVersionUID = 1L; /** * Id */ @id private String Id; /** * Owning company */ private String companyId; /** * Owning department */ private String officeId; /** * loginName */ private String loginName; /** * password */ private String password; /** * reversible password */ private String password2; /** * name */ private String name; /** * email */ private String email; /** * private String phone; /** * private String mobile; /** * userType */ private String userType; /** * Whether to login */ private String loginFlag; /** * private String delFlag; /** * private String securityKey; /** * Transient private Device Device;Copy the code

2.2UserAccountHolder Operations related to ThreadLocal

The fetching and using of the relevant local thread.

public class UserAccountHolder {

    private UserAccountHolder() {
    }

    private static final ThreadLocal<SysUser> threadLocal = new ThreadLocal<>();

    public static SysUser getUser() {
        return threadLocal.get();
    }

    public static void setUser(final SysUser user) {
        threadLocal.set(user);
    }

    public static void clear() { threadLocal.remove(); }}Copy the code

2.3 Enumeration of Tokens.

Public enum HttpHeaderKeyEnums {/** * User token */ token ("token"."Login with Token");

    private String code;
    private String desc;

    HttpHeaderKeyEnums(String code, String desc) {
        this.code = code;
        this.desc = desc;
    }

    public String getCode() {
        return code;
    }

    public String getDesc() {
        returndesc; }}Copy the code

2.3 Inherits the interceptor OncePerRequestFilter to achieve token acquisition and verification and device type acquisition.

AuthCacheService is a cache access, I use ehCache implementation implementation, there are a number of configuration implementation classes, relatively complicated will not stick out temporarily. I actually prefer redies myself, so you can try that.

public class AuthFilter extends OncePerRequestFilter {

    private PathMatcher ignoreUrlMatcher = new AntPathMatcher();

    @Autowired
    private AuthCacheService authCacheService;

    private String[] ignoreURLs = {
            "/"."/error"."/auth/login"."/webjars/**"."/swagger-resources/**"."/v2/**"."/swagger-ui.html"."/socket/**"."/integration/**"."/desktop.html/**"."/static/**"."/simulator/**"
    };


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        try {
            if (request.getMethod().equalsIgnoreCase(HttpMethod.OPTIONS.name())) {
                return;
            }
            String token = request.getHeader(HttpHeaderKeyEnums.TOKEN.getCode()) == null ? request.getParameter(HttpHeaderKeyEnums.TOKEN.getCode()) : request.getHeader(HttpHeaderKeyEnums.TOKEN.getCode());
            if (StringUtils.isBlank(token)) {
                this.noLogin(response);
                return; } // The user information cached after login is compared with this requestif(! AuthCacheService. ContainsLoginToken (token)) {/ login * * * not * / this. NoLogin (response);return; } / is logged in * * * * / / / after the success of the validation, access to all of the information users SysUser user = authCacheService. GetLoginToken (token); / / equipment information user. In the entity setDevice (DeviceUtils. GetCurrentDevice (request)); / / add full user entity in the ThreadLocal UserAccountHolder. SetUser (user); // Execute filterchain. doFilter(request, response); } finally { UserAccountHolder.clear(); } } @SneakyThrows private void noLogin(HttpServletResponse response) { response.setHeader(HttpHeaders.CONTENT_TYPE,"application/json; charset=UTF-8");
        response.sendError(HttpStatus.FORBIDDEN.value(), "Not logged in"); } @override protected Boolean shouldNotFilter(HttpServletRequest Request) {String requestPath = getRequestPath(request);for (String url : ignoreURLs) {
            if (ignoreUrlMatcher.match(url, requestPath)) {
                return true; }}return false;
    }

    private String getRequestPath(HttpServletRequest request) {
        String url = request.getServletPath();
        String pathInfo = request.getPathInfo();
        if(pathInfo ! = null) { url = org.springframework.util.StringUtils.hasLength(url) ? url + pathInfo : pathInfo; }returnurl; }}Copy the code

2.4 Inject interceptors

Set the priority level. Otherwise, the execution sequence may be incorrect and device information cannot be obtained.

@Configuration
public class FilterConfig {

    @Bean
    public AuthFilter AuthFilter() {
        return new AuthFilter();
    }

    @Bean
    public DeviceResolverRequestFilter deviceResolverRequestFilter() {return new DeviceResolverRequestFilter();
    }

    @Bean
    public FilterRegistrationBean<AuthFilter> authFilterRegistration() {
        FilterRegistrationBean<AuthFilter> registration = new FilterRegistrationBean<>();
        registration.setFilter(AuthFilter());
//        registration.addUrlPatterns(AppConst.APP_URL_PREFIX+"/ *");
        registration.setOrder(1);
        return registration;
    }

    @Bean
    public FilterRegistrationBean<DeviceResolverRequestFilter> deviceResolverRequestFilterRegistration() {
        FilterRegistrationBean<DeviceResolverRequestFilter> registration = new FilterRegistrationBean<>();
        registration.setFilter(deviceResolverRequestFilter());
        registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
        returnregistration; }}Copy the code

2.5 UserUtil gets the utility class for the parameters directly in the request. Includes direct equipment determination.

public class UserUtil {

    private UserUtil() {} // Public static SysUsergetUser() {
        return UserAccountHolder.getUser();
    }

    // officeId
    public static String getOfficeId() {
        SysUser user = UserAccountHolder.getUser();
        if (Objects.isNull(user)) {
            throw new BaseException(MessageEnum.ERROR_1010);
        }
        return user.getOfficeId();
    }

    // getUserId
    public static String getUserId() {
        SysUser user = UserAccountHolder.getUser();
        if (Objects.isNull(user)) {
            throw new BaseException(MessageEnum.ERROR_1010);
        }
        return user.getId();
    }

    // getToken
    public static String getToken() {
        SysUser user = UserAccountHolder.getUser();
        if (Objects.isNull(user)) {
            throw new BaseException(MessageEnum.ERROR_1010);
        }
        return user.getSecurityKey();
    }

    // getToken
    public static String getPassword() {
        SysUser user = UserAccountHolder.getUser();
        if (Objects.isNull(user)) {
            throw new BaseException(MessageEnum.ERROR_1010);
        }
        returnuser.getPassword(); } // Modify user public static voidsetUser(SysUser sysUser) {
        if(Objects.isNull(sysUser)) { throw new BaseException(MessageEnum.ERROR_1010); } UserAccountHolder.setUser(sysUser); } // Get isMobile public static BooleanisMobile() {
        SysUser user = UserAccountHolder.getUser();
        if (Objects.isNull(user)) {
            throw new BaseException(MessageEnum.ERROR_1010);
        }
        returnuser.getDevice().isMobile(); } // Get isNormal public static BooleanisNormal() {
        SysUser user = UserAccountHolder.getUser();
        if (Objects.isNull(user)) {
            throw new BaseException(MessageEnum.ERROR_1010);
        }
        returnuser.getDevice().isNormal(); } // get isTablet public static BooleanisTablet() {
        SysUser user = UserAccountHolder.getUser();
        if (Objects.isNull(user)) {
            throw new BaseException(MessageEnum.ERROR_1010);
        }
        returnuser.getDevice().isTablet(); }}Copy the code

2.6 Controller layer applications can retrieve information directly from UserUtil, instead of adding HttpServletRequest to retrieve information. Of course, it can also be applied to the corresponding Service layer can be directly obtained, and the device information can also be directly determined to achieve different.

/** * obtain all personal information ** @returnUser info */ @getMapping ("/user")
    @ApiOperation(value = "1.0.4 Interface for Querying All Personal Information", httpMethod = "GET")
    public ResultVo user() {
        SysUser sysUser = authService.user(UserUtil.getToken());
        return new ResultVo<>().setData(sysUser);
    }
Copy the code

3 summary

This is sufficient for relatively simple permission management. The main process is as follows: 1. Inject the device to obtain the relevant Bean.2. Inject the Bean to the interceptor and set the priority. 4. Use the local thread directly.