启动项目时报错如下:
java.lang.UnsupportedClassVersionError:org/springframework/boot/loader/JarLauncher : Unsupported major.minor version 52.0
一般jdk1.8 -----> springboot 2.5.x以下
jdk1.9 -----> springboot2.5.x以上
JWT + Redis + Spring拦截器
login请求:前端传来username和password,后台进行验证,验证通过之后根据用户id和用户名使用JWT技术生成用户唯一token,同时将用户信息缓存到Redis中,并且设置过期时间,返回token给前端。
其他请求:前端携带保存于header中的token,后端的前置拦截器preHandler()方法中获取token后验证token合法性,再通过token获取用户信息,根据用户id和用户名查询Redis中是否存在用户信息 ,存在则放行。
权限表
角色表
1. 创建注解@AuthRequired 和权限拦截器PermissionIntercepter
2. 前端发送请求被springboot的权限拦截器PermissionIntercepter拦截。
3. 权限拦截器中通过反射获取拦截的方法的信息,判断方法上是否存在@AuthRequired注解,不存在就直接放行。
4. 存在即根据token获取用户的权限列表,与request.getUrl()对比,用户存在该权限就放行,不存在就拦截。
权限拦截器代码
package com.cngrain.website.interceptor;
import com.cngrain.website.annotation.AuthRequired;
import com.cngrain.website.common.utils.JwtUtils;
import com.cngrain.website.common.utils.RedisUtil;
import com.cngrain.website.entity.User;
import com.cngrain.website.interceptor.exception.WebsiteException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;
@Component
public class PermissionInterceptor implements HandlerInterceptor {
@Autowired
RedisUtil redisUtil;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 如果不是映射到方法不拦截 直接通过
if (!(handler instanceof HandlerMethod)) {
return true;
}
//获取用户Id
String id = JwtUtils.getMemberIdByJwtToken(request);
User user = (User) redisUtil.get("website:user:info" + id);
if(user.getRoles().equals("admin")) {//admin 最高权限
return true;
}
//通过反射, 获取方法和和方法上的注解信息
Method method = ((HandlerMethod) handler).getMethod();
Annotation[] declaredAnnotations = method.getDeclaredAnnotations();
Boolean authRequired = false;
for (Annotation annotation : declaredAnnotations) {
if(annotation.annotationType() == AuthRequired.class) {
authRequired = true;
break;
}
}
if(authRequired) {
//请求的url
String requestURI = request.getRequestURI();
//获取用户的权限列表,存在redis中的
Set<String> set =(HashSet) redisUtil.get("website:user:permission" + id);
if(set.contains(requestURI)) { //有权限
return true;
}
throw new WebsiteException(201,"权限不足");
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
}
登录代码
package com.cngrain.website.service.impl;
import com.cngrain.website.common.Result;
import com.cngrain.website.common.utils.JwtUtils;
import com.cngrain.website.common.utils.RedisUtil;
import com.cngrain.website.entity.Permission;
import com.cngrain.website.entity.Role;
import com.cngrain.website.entity.User;
import com.cngrain.website.interceptor.exception.WebsiteException;
import com.cngrain.website.mapper.PermissionMapper;
import com.cngrain.website.mapper.RoleMapper;
import com.cngrain.website.mapper.UserMapper;
import com.cngrain.website.service.LoginService;
import com.cngrain.website.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashSet;
import java.util.Set;
@Service
public class LoginServiceImpl implements LoginService {
@Autowired
RedisUtil redisUtil;
@Autowired
UserService userService;
@Autowired
UserMapper userMapper;
@Autowired
RoleMapper roleMapper;
@Autowired
PermissionMapper permissionMapper;
@Override
public Result login(String username, String password) {
User one = userMapper.getByUsernamePassword(username,password);
if(one == null) {
throw new WebsiteException(201,"用户名或者密码错误");
}
//创建Set集合,用于存放权限url
Set<String> permissionSet = new HashSet<>();
//获取用户角色信息
String[] roles = one.getRoles().split(",");
for (String roleName : roles) {
Role role = roleMapper.getPermissionByRoleName(roleName);
//根据用户角色获取用户权限列表 格式--(1,2,3,4)存储的为权限id
String rolePermission = role.getRolePermission();
String[] split = rolePermission.split(",");
for (String id : split) {
if(id.equals("")) {
break;
}
//根据id获取权限url
Permission permission = permissionMapper.getPermissionUrlById(Integer.valueOf(id));
permissionSet.add(permission.getPermissionUrl());
}
}
//生成token
String token = JwtUtils.getJwtToken(one.getId().toString(),one.getName());
//redis存储用户信息,设置过期时间
redisUtil.set("website:user:info" + one.getId(),one,3000);
//将权限集合存放到redis中
redisUtil.set("website:user:permission" + one.getId().toString(),permissionSet);
// 返回token
return Result.ok().data("token",token);
}
}
拦截器配置代码
package com.cngrain.website.config;
import com.cngrain.website.interceptor.LoginInterceptor;
import com.cngrain.website.interceptor.PermissionInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
LoginInterceptor loginInterceptor;
@Autowired
PermissionInterceptor permissionInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor) //登录拦截器
.addPathPatterns("/**") //拦截
.excludePathPatterns("/login/**","/register/**"); //放行登录与注册
registry.addInterceptor(permissionInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/login/**","/register/**");
}
}
注解代码
package com.cngrain.website.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD,ElementType.TYPE}) //作用域 方法和类上
@Retention(RetentionPolicy.RUNTIME)
public @interface AuthRequired {}
ApplicationHome applicationHome = new ApplicationHome(this.getClass());
String classpath = applicationHome.getDir().getAbsolutePath()
检查path中的%JAVA_HOME%\bin的位置,一般是上面的环境变量中存在其他版本的jdk,解决办法:
1:%JAVA_HOME%\bin上移
2: 找出其他版本jdk位置然后删除
如图错误信息
解决方案:设置Shared build process heap size (Mbytes): 的值
补充:之前错误由于在windows环境使用了linux版本的jdk导致的
该错误是linux系统空间不足造成的,释放磁盘空间即可
ctrl + p -------------------------提示方法参数
ctrl + o -------------------------重写父类方法
shift + shift / ctrl + shift + r -全局搜索
df -h -----------------------------查看磁盘空间使用情况
tail -f xxxx.log ------------------动态查看文件信息
tail -n 100 xxxx.log --------------查看日志后100行
git clone xxxx.git ---------------拉取代码
git clone xxxx.git -b [分支名称] ---拉取指定分支代码