增加工具类
parent
df866d4d27
commit
38f92a9679
6
pom.xml
6
pom.xml
|
@ -16,7 +16,7 @@
|
|||
<java.version>1.8</java.version>
|
||||
<mybatis-plus-boot-starter.version>3.3.0</mybatis-plus-boot-starter.version>
|
||||
<hutool.version>5.7.20</hutool.version>
|
||||
<knife4j-micro-spring-boot-starter.version>3.0.3</knife4j-micro-spring-boot-starter.version>
|
||||
<knife4j-spring-boot-starter.version>2.0.9</knife4j-spring-boot-starter.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
@ -98,8 +98,8 @@
|
|||
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>knife4j-micro-spring-boot-starter</artifactId>
|
||||
<version>${knife4j-micro-spring-boot-starter.version}</version>
|
||||
<artifactId>knife4j-spring-boot-starter</artifactId>
|
||||
<version>${knife4j-spring-boot-starter.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>javax.validation</groupId>
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
package com.jwl.driver.server.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 权限配置类
|
||||
*/
|
||||
@ConfigurationProperties(prefix = AuthConfig.PREFIX)
|
||||
@Component
|
||||
@Data
|
||||
public class AuthConfig {
|
||||
|
||||
|
||||
public static final String PREFIX = "driver.auth-config";
|
||||
|
||||
/**
|
||||
* 约定为若 preAuth 为 true,则所有请求(除不需权限校验url集合noAuthEndPoints外)都需要身份认证
|
||||
* 为 false,则所有请求(除需要权限校验url集合needAuthEndPoints外)都不需要身份认证
|
||||
*/
|
||||
private Boolean preAuth;
|
||||
|
||||
/**
|
||||
* 不需权限校验 url 集合
|
||||
*/
|
||||
private String[] noAuthEndPoints;
|
||||
|
||||
/**
|
||||
* 必须验证的权限 url 集合
|
||||
*/
|
||||
private String[] needAuthEndPoints;
|
||||
|
||||
}
|
|
@ -26,7 +26,8 @@ public class CorsConfig implements WebMvcConfigurer {
|
|||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(authInterceptor).addPathPatterns("/**").excludePathPatterns("/**/login",
|
||||
// "/error",
|
||||
"/error",
|
||||
"/webjars/**",
|
||||
"/doc.html");
|
||||
}
|
||||
|
||||
|
@ -56,11 +57,6 @@ public class CorsConfig implements WebMvcConfigurer {
|
|||
registry.addResourceHandler("doc.html")
|
||||
.addResourceLocations("classpath:/META-INF/resources/");
|
||||
|
||||
/**
|
||||
* 配置swagger-ui显示文档
|
||||
*/
|
||||
registry.addResourceHandler("swagger-ui.html")
|
||||
.addResourceLocations("classpath:/META-INF/resources/");
|
||||
/** 公共部分内容 */
|
||||
registry.addResourceHandler("/webjars/**")
|
||||
.addResourceLocations("classpath:/META-INF/resources/webjars/");
|
||||
|
|
|
@ -8,12 +8,11 @@ import io.swagger.annotations.Api;
|
|||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
|
@ -35,9 +34,17 @@ public class TdSysUserController {
|
|||
|
||||
@ApiOperation("用户登陆")
|
||||
@PostMapping("/login")
|
||||
public BaseResponse login(@RequestBody LoginUserDto loginUserDto) throws Exception {
|
||||
public BaseResponse login(@RequestBody LoginUserDto loginUserDto) {
|
||||
log.info("用户登录======>loginUserDto:{}", loginUserDto);
|
||||
return BaseResponse.success(userService.login(loginUserDto));
|
||||
}
|
||||
|
||||
|
||||
@ApiOperation("用户登出")
|
||||
@GetMapping("/loginOut")
|
||||
public BaseResponse loginOut(){
|
||||
log.info("用户登出======>{}", LocalDateTime.now());
|
||||
return BaseResponse.success(userService.loginOut());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
package com.jwl.driver.server.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(chain = true)
|
||||
public class SecurityUser implements Serializable {
|
||||
|
||||
/**
|
||||
* 用户标识
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
private String userName;
|
||||
|
||||
|
||||
/**
|
||||
* 用户token
|
||||
*/
|
||||
private String token;
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package com.jwl.driver.server.filter;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.jwl.driver.server.util.TokenThreadUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* 线程保持当前token
|
||||
*/
|
||||
@Component
|
||||
public class TokenFilter extends OncePerRequestFilter {
|
||||
private static final Logger log = LoggerFactory.getLogger(TokenFilter.class);
|
||||
|
||||
|
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
|
||||
String requestTokenHeader = request.getHeader("Authorization");
|
||||
if (StrUtil.isBlank(requestTokenHeader)) {
|
||||
log.warn("Bearer token 为空");
|
||||
filterChain.doFilter((ServletRequest) request, (ServletResponse) response);
|
||||
return;
|
||||
}
|
||||
|
||||
TokenThreadUtil.setToken(requestTokenHeader);
|
||||
filterChain.doFilter(request, response);
|
||||
}
|
||||
}
|
|
@ -1,14 +1,23 @@
|
|||
package com.jwl.driver.server.interceptor;
|
||||
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.core.util.BooleanUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.jwl.driver.server.config.AuthConfig;
|
||||
import com.jwl.driver.server.constant.ErrorCode;
|
||||
import com.jwl.driver.server.exception.BusinessException;
|
||||
import com.jwl.driver.server.redis.RedisCache;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
|
@ -18,29 +27,62 @@ import java.util.Objects;
|
|||
*/
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class AuthInterceptor implements HandlerInterceptor {
|
||||
|
||||
@Autowired
|
||||
private RedisCache redisCache;
|
||||
|
||||
@Resource
|
||||
private AuthConfig authConfig;
|
||||
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
String requestURI = request.getRequestURI();
|
||||
if (requestURI.contains("doc.html")){
|
||||
return true;
|
||||
}
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
response.setContentType("text/html;charset=utf-8");
|
||||
String token = request.getHeader("token");
|
||||
if (StringUtils.isEmpty(token)) {
|
||||
response.getWriter().print("用户未登录,请登录后操作!");
|
||||
return false;
|
||||
String requestTokenHeader = request.getHeader("Authorization");
|
||||
|
||||
Boolean preAuth = authConfig.getPreAuth();
|
||||
ArrayList<String> noAuthEndPoints = ListUtil.toList(authConfig.getNoAuthEndPoints());
|
||||
ArrayList<String> needAuthEndPoints = ListUtil.toList(authConfig.getNeedAuthEndPoints());
|
||||
|
||||
if (StrUtil.isBlank(requestTokenHeader)) {
|
||||
log.warn("Authorization token 为空");
|
||||
}
|
||||
Object loginStatus = redisCache.getCacheObject(token);
|
||||
if( Objects.isNull(loginStatus)){
|
||||
response.getWriter().print("登陆异常,请查看!");
|
||||
return false;
|
||||
|
||||
// preAuth = false,则所有请求(除需要权限校验url集合needAuthEndPoints外)都不需要身份认证
|
||||
if (BooleanUtil.isFalse(preAuth)) {
|
||||
Boolean contains = needAuthEndPoints.contains(requestURI);
|
||||
// 必须登录的接口 && token为空
|
||||
if (contains && StrUtil.isBlank(requestTokenHeader)) {
|
||||
throw new BusinessException(ErrorCode.AUTH_ERROR, "尚未授权登录");
|
||||
}
|
||||
}else {
|
||||
// preAuth = true;
|
||||
// 配置文件无需登录的接口
|
||||
Boolean contains = noAuthEndPoints.contains(requestURI);
|
||||
// 具备排除标志的接口
|
||||
Boolean excludeFlag = Boolean.FALSE;
|
||||
for (String exclude : needAuthEndPoints) {
|
||||
if (requestURI.contains(exclude)) {
|
||||
excludeFlag = Boolean.TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!contains && !excludeFlag && StrUtil.isBlank(requestTokenHeader)) {
|
||||
throw new BusinessException(ErrorCode.AUTH_ERROR, "尚未授权登录");
|
||||
}
|
||||
}
|
||||
|
||||
if (StrUtil.isNotBlank(requestTokenHeader)){
|
||||
Object loginStatus = redisCache.getCacheObject(requestTokenHeader);
|
||||
if( Objects.isNull(loginStatus)){
|
||||
throw new BusinessException(ErrorCode.AUTH_ERROR, "登陆已过期");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,5 +15,16 @@ import com.jwl.driver.server.vo.LoginUserVo;
|
|||
*/
|
||||
public interface ITdSysUserService extends IService<TdSysUser> {
|
||||
|
||||
/**
|
||||
* 用户登陆
|
||||
* @param loginUserDto
|
||||
* @return
|
||||
*/
|
||||
LoginUserVo login(LoginUserDto loginUserDto);
|
||||
|
||||
/**
|
||||
* 用户登出
|
||||
* @return
|
||||
*/
|
||||
Boolean loginOut();
|
||||
}
|
||||
|
|
|
@ -1,17 +1,22 @@
|
|||
package com.jwl.driver.server.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.jwl.driver.server.dto.LoginUserDto;
|
||||
import com.jwl.driver.server.entity.TdSysUser;
|
||||
import com.jwl.driver.server.exception.BusinessException;
|
||||
import com.jwl.driver.server.mapper.TdSysUserMapper;
|
||||
import com.jwl.driver.server.redis.RedisCache;
|
||||
import com.jwl.driver.server.service.ITdSysUserService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.jwl.driver.server.util.TokenThreadUtil;
|
||||
import com.jwl.driver.server.vo.LoginUserVo;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
|
@ -29,13 +34,24 @@ public class TdSysUserServiceImpl extends ServiceImpl<TdSysUserMapper, TdSysUser
|
|||
private RedisCache redisCache;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public LoginUserVo login(LoginUserDto loginUserDto) {
|
||||
//XI
|
||||
//todo 这里还需要校验验证码
|
||||
|
||||
LambdaQueryWrapper<TdSysUser> cond = new LambdaQueryWrapper<TdSysUser>()
|
||||
.eq(TdSysUser::getPhone,"18255439337");
|
||||
//用户不存在则直接注册登陆
|
||||
TdSysUser tdSysUser = this.baseMapper.selectOne(cond);
|
||||
if (tdSysUser == null){
|
||||
//创建用户
|
||||
tdSysUser = new TdSysUser()
|
||||
.setUserName("车友")
|
||||
.setAvatar("")
|
||||
.setPhone(loginUserDto.getPhone())
|
||||
.setCreateTime(LocalDateTime.now());
|
||||
int insert = this.getBaseMapper().insert(tdSysUser);
|
||||
if (insert != 1){
|
||||
throw new BusinessException("用户注册异常");
|
||||
}
|
||||
}
|
||||
|
||||
String token = UUID.randomUUID().toString();
|
||||
|
@ -45,8 +61,14 @@ public class TdSysUserServiceImpl extends ServiceImpl<TdSysUserMapper, TdSysUser
|
|||
loginUserVo.setToken(token);
|
||||
|
||||
return loginUserVo;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Boolean loginOut() {
|
||||
String token = TokenThreadUtil.getToken();
|
||||
if (StrUtil.isNotBlank(token)){
|
||||
redisCache.deleteObject(token);
|
||||
}
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
package com.jwl.driver.server.util;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.jwl.driver.server.constant.ErrorCode;
|
||||
import com.jwl.driver.server.dto.SecurityUser;
|
||||
import com.jwl.driver.server.entity.TdSysUser;
|
||||
import com.jwl.driver.server.exception.BusinessException;
|
||||
import com.jwl.driver.server.redis.RedisCache;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 获取当前登录人信息
|
||||
*/
|
||||
public class SecurityUtil {
|
||||
private static final Logger log = LoggerFactory.getLogger(SecurityUtil.class);
|
||||
|
||||
private static final RedisCache redisCache = SpringAsyncUtil.<RedisCache>getBean(RedisCache.class);
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前登录人信息
|
||||
* @return
|
||||
*/
|
||||
public static SecurityUser getLoginUser() {
|
||||
String token = TokenThreadUtil.getToken();
|
||||
if (StrUtil.isBlank(token))
|
||||
throw new BusinessException(ErrorCode.AUTH_ERROR, "尚未登录");
|
||||
SecurityUser securityUser = null;
|
||||
TdSysUser tdSysUser = redisCache.getCacheObject(token);
|
||||
|
||||
if (Objects.isNull(securityUser)){
|
||||
throw new BusinessException(ErrorCode.AUTH_ERROR, "登录信息已失效");
|
||||
}
|
||||
BeanUtils.copyProperties(tdSysUser,securityUser);
|
||||
securityUser.setToken(token);
|
||||
|
||||
return securityUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前登录人用户编号
|
||||
* @return
|
||||
*/
|
||||
public static Long getUserId() {
|
||||
Long userId = null;
|
||||
SecurityUser loginUser = SecurityUtil.getLoginUser();
|
||||
if (null != loginUser) {
|
||||
userId = loginUser.getUserId();
|
||||
}
|
||||
|
||||
return userId;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package com.jwl.driver.server.util;
|
||||
|
||||
|
||||
import org.springframework.aop.framework.AopContext;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
|
||||
public final class SpringAsyncUtil implements BeanFactoryPostProcessor, ApplicationContextAware {
|
||||
private static ConfigurableListableBeanFactory beanFactory;
|
||||
|
||||
private static ApplicationContext applicationContext;
|
||||
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
||||
SpringAsyncUtil.beanFactory = beanFactory;
|
||||
}
|
||||
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
SpringAsyncUtil.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
public static <T> T getBean(String name) throws BeansException {
|
||||
return (T)beanFactory.getBean(name);
|
||||
}
|
||||
|
||||
public static <T> T getBean(Class<T> clz) throws BeansException {
|
||||
T result = (T)beanFactory.getBean(clz);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static boolean containsBean(String name) {
|
||||
return beanFactory.containsBean(name);
|
||||
}
|
||||
|
||||
public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
|
||||
return beanFactory.isSingleton(name);
|
||||
}
|
||||
|
||||
public static Class<?> getType(String name) throws NoSuchBeanDefinitionException {
|
||||
return beanFactory.getType(name);
|
||||
}
|
||||
|
||||
public static String[] getAliases(String name) throws NoSuchBeanDefinitionException {
|
||||
return beanFactory.getAliases(name);
|
||||
}
|
||||
|
||||
public static <T> T getAopProxy(T invoker) {
|
||||
return (T)AopContext.currentProxy();
|
||||
}
|
||||
|
||||
public static String[] getActiveProfiles() {
|
||||
return applicationContext.getEnvironment().getActiveProfiles();
|
||||
}
|
||||
|
||||
public static String getActiveProfile() {
|
||||
String[] activeProfiles = getActiveProfiles();
|
||||
return (activeProfiles.length > 0) ? activeProfiles[0] : null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.jwl.driver.server.util;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
/**
|
||||
* 线程变量-token
|
||||
*/
|
||||
public class TokenThreadUtil {
|
||||
private static ThreadLocal<String> threadLocal = new ThreadLocal<>();
|
||||
|
||||
public static void setToken(String token) {
|
||||
if (StrUtil.isNotBlank(token))
|
||||
threadLocal.set(token);
|
||||
}
|
||||
|
||||
public static String getToken() {
|
||||
return threadLocal.get();
|
||||
}
|
||||
|
||||
public static void remove() {
|
||||
threadLocal.remove();
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
server:
|
||||
port: 8888
|
||||
# servlet:
|
||||
# context-path: '/driver-api'
|
||||
servlet:
|
||||
context-path: '/driver-api'
|
||||
|
||||
spring:
|
||||
application:
|
||||
|
@ -29,3 +29,18 @@ pagehelper:
|
|||
knife4j:
|
||||
# 是否开启增强模式
|
||||
enable: true
|
||||
|
||||
# 是否需要校验token
|
||||
driver:
|
||||
auth-config:
|
||||
# 约定为若 preAuth 为 true,则所有请求(除不需权限校验url集合noAuthEndPoints外)都需要身份认证
|
||||
# 为 false,则所有请求(除需要权限校验url集合needAuthEndPoints外)都不需要身份认证
|
||||
preAuth: true
|
||||
# 不需权限校验url集合
|
||||
noAuthEndPoints:
|
||||
- /driver-api/v2/api-docs
|
||||
- /driver-api/swagger-resources
|
||||
- /driver-api/favicon.ico
|
||||
|
||||
# 需要权限校验url集合
|
||||
needAuthEndPoints:
|
||||
|
|
Loading…
Reference in New Issue