分享一个简单java的登录权限实现过程吧,复制即用

我这里是用拦截器实现的,使用的redis,springboot2。废话不多说,上代码吧

定义验证等级枚举:

public enum  AuthorityType {
    //不验证
    Nocheck,
    //只验证登录
    CheckLongin,
    // 登录和权限都验证
    CheckLevel0,//用户等级为0权限
    CheckLevel1,//用户等级为1权限
    CheckLevel2,//用户等级为2权限
}

定义接口:

@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Authority {
    // 默认验证
    AuthorityType value() default AuthorityType.Nocheck;
}

定义拦截器:


//登录权限验证拦截器
@Slf4j
@Aspect
@Component
public class AuthorityAnnotationInterceptor extends HandlerInterceptorAdapter {
	//redis注入
    @Autowired
    private StringRedisTemplate redisTemplate;
	//用户业务层接口
    @Autowired
    private IWjUserService wjUserService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {

        if (handler instanceof HandlerMethod) {
            HandlerMethod hm = (HandlerMethod) handler;

            Class<?> clazz = hm.getBeanType();
            Method m = hm.getMethod();
            try {
                if (clazz != null && m != null) {
                    boolean isClzAnnotation = clazz.isAnnotationPresent(Authority.class);
                    boolean isMethondAnnotation = m.isAnnotationPresent(Authority.class);
                    Authority authority = null;
                    // 如果方法和类声明中同时存在这个注解,那么方法中的会覆盖类中的设定。
                    //方法上的@Authority注解优先级比类高
                    if (isMethondAnnotation) {
                        authority = m.getAnnotation(Authority.class);
                    } else if (isClzAnnotation) {
                        authority = clazz.getAnnotation(Authority.class);
                    }

                    response.setCharacterEncoding("UTF-8");
                    response.setContentType("application/json; charset=utf-8");

                    if (authority != null) {
                        if (AuthorityType.Nocheck == authority.value()) {
                            // 标记为不验证,放行
                            return true;
                        } else{
							//验证登录
							//encrytestr 为用户登录生成的一个标识,由userId和userToken加密得来的,登录后将encrytestr存于redis中,登录后将encrytestr返回前端,前端将其作为公共参数放入请求头

							//获取请求头中的encrytestr
                            String encrytestr = request.getHeader("encrytestr");//获取encrytestr
                            if(StringUtils.isBlank(encrytestr)){
                                response.getWriter().write(JSON.toJSONString(new AjaxResult(StatusCode.ERROR_CODE_40000,"token过期,请重新登录")));
                                return false;
                            }
                          	//从redis中查找encrytestr存不存在
                            String userString = redisTemplate.opsForValue().get("ulogin"+encrytestr);
                            System.out.println(userString);
                            if(StringUtils.isBlank(userString)){
                                response.getWriter().write(JSON.toJSONString(new AjaxResult(StatusCode.ERROR_CODE_40000,"token过期,请重新登录")));
                                return false;
                            }
							
							//将encrytestr进行解密得到token和userid
                            Map<String, String> map = CommenUtils.decryptUserIdAndTokenByStr(encrytestr);
                            String token = map.get("token");
                            String userId = map.get("userId");
                            if(StringUtils.isBlank(token)||StringUtils.isBlank(userId)){
                                response.getWriter().write(JSON.toJSONString(new AjaxResult(StatusCode.ERROR_CODE_40000,"token错误")));
                                return false;
                            }
							
							
                            WjUser wju = this.wjUserService.getById(userId);
                            if (wju == null) {
                                response.getWriter().write(JSON.toJSONString(new AjaxResult(StatusCode.ERROR_CODE_40000,"token错误")));
                                return false;
                            }
							//验证用户token是否过期
                            if (!wju.getToken().equals(token)) {
                                response.getWriter().write(JSON.toJSONString(new AjaxResult(StatusCode.ERROR_CODE_40000,"token过期,请重新登录")));
                                return false;
                            }
                            if (AuthorityType.CheckLongin == authority.value()) {
                                // 不验证权限,验证是否登录
                                // TODO:
                                return true;
                            }else{
                            
								//验证用户等级

                                if (AuthorityType.CheckLevel0 == authority.value()) {
                                    // 不验证权限,验证是否登录
                                    // TODO:
                                    if(wju.getLevel()!=0){
                                        response.getWriter().write(JSON.toJSONString(new AjaxResult(StatusCode.ERROR_CODE_40000,"权限不符")));
                                        return false;
                                    }
                                    return true;
                                }else if (AuthorityType.CheckLevel1 == authority.value()) {
                                    // 不验证权限,验证是否登录
                                    // TODO:
                                    if(wju.getLevel()!=1){
                                        response.getWriter().write(JSON.toJSONString(new AjaxResult(StatusCode.ERROR_CODE_40000,"权限不符")));
                                        return false;
                                    }
                                    return true;
                                }else if (AuthorityType.CheckLevel2 == authority.value()) {
                                    // 不验证权限,验证是否登录
                                    // TODO:
                                    if(wju.getLevel()!=2){
                                        response.getWriter().write(JSON.toJSONString(new AjaxResult(StatusCode.ERROR_CODE_40000,"权限不符")));
                                        return false;
                                    }
                                    return true;
                                } else {
                                    // 验证登录及权限
                                    // TODO:
                                    //response.getWriter().write(JSON.toJSONString(new AjaxResult(StatusCode.ERROR_CODE_40000,"权限不符")));
                                    return true;
                                }
                            }
                        }
                    }
                    // 未通过验证,返回提示json
                   /* 
                    response.getWriter().write(JSON.toJSONString(new AjaxResult(StatusCode.ERROR_CODE_40000,"权限错误")));*/
                    return true;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
       /* 
        response.getWriter().write(JSON.toJSONString(new AjaxResult(StatusCode.ERROR_CODE_40000,"权限错误")));*/
        return true;
    }

}

配置拦截器:

@Configuration
public class WebMvcConfiguration  implements WebMvcConfigurer {
    @Autowired
    AuthorityAnnotationInterceptor authorityAnnotationInterceptor;
    @Override   //拦截器配置
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(authorityAnnotationInterceptor) //拦截器注册对象
                .addPathPatterns("/**") //指定要拦截的请求
                .excludePathPatterns("/wjUser/loginUser"); //排除请求
    }
}

登录成功之后:

		String aesKey = "fd980019fc95df40f0ed43731a11219f";
		//生成userToken,并将token和userid加密成encryptStr,存于redis中
 		String key = "ulogin";
        if(redisTemplate.hasKey(key+getuser.getEncrytestr())){
            redisTemplate.delete(key+getuser.getEncrytestr());
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String format = simpleDateFormat.format(new Date());
        String token = CommenUtils.jdkAESEncrypt(aesKey, format + "," + getuser.getUseraccount());
        getuser.setToken(token);
        String encrypt = CommenUtils.encryptGameUserIdAndToken(getuser.getId(), getuser.getToken());
        getuser.setEncrytestr(encrypt);
        getuser.setLastlogintime(new Timestamp(System.currentTimeMillis()));
        wjUserService.updateById(getuser);

        getuser.setPassword("");

        redisTemplate.opsForValue().set(key+getuser.getEncrytestr(), JSON.toJSONString(getuser),60 * 60 * 24, TimeUnit.SECONDS);

        return new AjaxResult(getuser,"登录成功");

工具类里的一些代码:

		@Slf4j
public class CommenUtils {
      public static Map<String,String> decryptUserIdAndTokenByStr(String encryptStr) {
        String gameAesKey = "Ae980019bc59fd40f0ef34798e11210a";
        String decryptStr = CommenUtils.jdkAESDecrypt(gameAesKey, encryptStr);
//        log.info("游戏token解密完的字符串:"+decryptStr);
        Map<String,String> map = new HashMap<>();
        String[] split = decryptStr.split(",");
        if (split.length != 2){
            return null;
        }
        map.put("userId",split[0]);
        map.put("token",split[1]);
        return map;
    }
 /*
     * AES加密
    * @prama HexStringkey 密钥
    * @prama content 加密的内容
    * */
    public static String jdkAESEncrypt(String HexStringkey,String content) {

        try {
            byte[] byteskey = Hex.decodeHex(HexStringkey.toCharArray());
            //转换key
            Key convertSecretKey = new SecretKeySpec(byteskey, "AES");

            //加密
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, convertSecretKey);
            byte[] encryptResult = cipher.doFinal(content.getBytes());
            String encryptResultStr = Hex.encodeHexString(encryptResult);
            log.info("jdk des encrypt:" + encryptResultStr);
            return encryptResultStr;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
 public static String encryptGameUserIdAndToken(String userId,String token) {
        String gameAesKey = "Ae980019bc59fd40f0ef34798e11210a";
        System.out.println("123123");
        System.out.println(gameAesKey);
        System.out.println(userId);
        System.out.println(token);
        String encryptStr = CommenUtils.jdkAESEncrypt(gameAesKey, userId+","+token);
        return encryptStr;
    }
     /*
     * AES解密
     * @prama HexStringkey 密钥
     * @prama encryptResultStr 解密的内容
     * */
    public static String jdkAESDecrypt(String HexStringkey,String encryptResultStr) {
        try {
            byte[] byteskey = Hex.decodeHex(HexStringkey.toCharArray());
            //转换key
            Key convertSecretKey = new SecretKeySpec(byteskey, "AES");
            // 解密
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, convertSecretKey);
            byte[] encryptResult = Hex.decodeHex(encryptResultStr.toCharArray());
            byte[] decryptResult = cipher.doFinal(encryptResult);
            String decryptStr = new String(decryptResult);
            log.info("jdk des decrypt:" + decryptStr);
            return decryptStr;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
}

使用的时候就直接在方法上@Authority(AuthorityType.CheckLevel0)就可以
在控制器内也可以获取用户id

String encrytestr = request.getHeader("encrytestr");
 //token过期验证
Map<String, String> map = CommenUtils.decryptUserIdAndTokenByStr(encrytestr);
String userId = map.get("userId");

WjUser wju = this.wjUserService.getById(userId);

分享差不多就结束了,复制的话需要将用户换成你们自己的,我这里权限验证只是分了个等级,大家可以根据自己的需求自行更改,代码还不是很完善,大家有什么问题和建议可以在评论留言。

感谢大家的阅读

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐