feat: 增加了 jwt 验证方式。
This commit is contained in:
@@ -70,6 +70,10 @@ dependencies {
|
||||
// Excel处理
|
||||
implementation("org.apache.poi:poi:5.2.5")
|
||||
implementation("org.apache.poi:poi-ooxml:5.2.5")
|
||||
|
||||
// Redis
|
||||
implementation("org.springframework.boot:spring-boot-starter-data-redis")
|
||||
implementation("org.apache.commons:commons-pool2")
|
||||
}
|
||||
|
||||
tasks.withType<Test> {
|
||||
|
||||
@@ -28,7 +28,9 @@ public class UrlPermissionAuthorizationManager implements AuthorizationManager<R
|
||||
|
||||
HttpServletRequest request = context.getRequest();
|
||||
String requestURI = request.getRequestURI();
|
||||
if (antPathMatcher.match("/auth/user/me", requestURI)) {
|
||||
// 公开接口直接放行
|
||||
if (antPathMatcher.match("/auth/user/me", requestURI)
|
||||
|| antPathMatcher.match("/open/**", requestURI)) {
|
||||
return new AuthorizationDecision(true);
|
||||
}
|
||||
Authentication auth = authentication.get();
|
||||
|
||||
@@ -4,47 +4,66 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.niuan.erp.common.base.BaseResult;
|
||||
import com.niuan.erp.common.base.LoginUser;
|
||||
import com.niuan.erp.common.bean.UrlPermissionAuthorizationManager;
|
||||
import com.niuan.erp.common.security.JwtAuthenticationFilter;
|
||||
import com.niuan.erp.common.security.TokenService;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.core.session.SessionRegistry;
|
||||
import org.springframework.security.core.session.SessionRegistryImpl;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.session.ConcurrentSessionFilter;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
import org.springframework.web.cors.CorsConfiguration;
|
||||
import org.springframework.web.cors.CorsConfigurationSource;
|
||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Security配置类 - 同时支持Session和JWT两种认证方式
|
||||
* - Web端(后台管理):使用传统Session方式(基于Cookie)
|
||||
* - 小程序端:使用JWT方式(基于Token)
|
||||
*/
|
||||
@Configuration
|
||||
@EnableWebSecurity // 启用 Web 安全
|
||||
@EnableWebSecurity
|
||||
@EnableMethodSecurity
|
||||
@RequiredArgsConstructor
|
||||
public class SecurityConfig {
|
||||
|
||||
private final UrlPermissionAuthorizationManager urlPermissionAuthorizationManager;
|
||||
|
||||
private final JwtAuthenticationFilter jwtAuthenticationFilter;
|
||||
|
||||
private final TokenService tokenService;
|
||||
|
||||
private final UserDetailsService userDetailsService;
|
||||
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain filterChain(HttpSecurity http, SessionRegistry sessionRegistry) throws Exception {
|
||||
http
|
||||
// 👇 1. 启用 CSRF
|
||||
// 禁用 CSRF(JWT需要禁用,Session方式通过其他方式防护)
|
||||
.csrf(csrf -> csrf.disable())
|
||||
|
||||
.cors(cors -> cors.configurationSource(corsConfigurationSource()))
|
||||
|
||||
// 👇 2. 设置 Session
|
||||
// 设置 Session(支持Session方式,同时允许JWT无状态请求)
|
||||
.sessionManagement(session -> session
|
||||
.maximumSessions(1)
|
||||
.maxSessionsPreventsLogin(false)
|
||||
.sessionRegistry(sessionRegistry))
|
||||
|
||||
// 👇 3. 请求授权规则
|
||||
// 请求授权规则
|
||||
.authorizeHttpRequests(authz -> authz
|
||||
.requestMatchers(
|
||||
"/v3/api-docs/**", "/v3/api-docs",
|
||||
@@ -52,24 +71,25 @@ public class SecurityConfig {
|
||||
"/swagger-ui.html",
|
||||
"/webjars/**",
|
||||
"/doc.html",
|
||||
"/favicon.ico").permitAll()
|
||||
"/favicon.ico",
|
||||
"/open/**",
|
||||
"/api/auth/**").permitAll() // 小程序登录接口公开
|
||||
.anyRequest().authenticated()
|
||||
)
|
||||
|
||||
//
|
||||
// 表单登录配置(Web端使用)
|
||||
.formLogin(form -> form
|
||||
.loginProcessingUrl("/auth/login") // 指定登录提交地址
|
||||
.loginProcessingUrl("/auth/login")
|
||||
.successHandler((request, response, authentication) -> {
|
||||
// 登录成功:返回 JSON
|
||||
// Web端登录成功:返回简单JSON
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
LoginUser user = (LoginUser) authentication.getPrincipal();
|
||||
response.getWriter().write(new ObjectMapper().writeValueAsString(BaseResult.success()));
|
||||
})
|
||||
.failureHandler((request, response, exception) -> {
|
||||
// 登录失败:返回 JSON
|
||||
response.setStatus(HttpStatus.OK.value());
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.getWriter().write(new ObjectMapper().writeValueAsString(BaseResult.error(3, exception.getMessage())));
|
||||
response.getWriter().write(new ObjectMapper().writeValueAsString(
|
||||
BaseResult.error(3, exception.getMessage())));
|
||||
})
|
||||
)
|
||||
.logout(logout -> logout
|
||||
@@ -78,47 +98,50 @@ public class SecurityConfig {
|
||||
.deleteCookies("JSESSIONID")
|
||||
.clearAuthentication(true)
|
||||
.logoutSuccessHandler((request, response, authentication) -> {
|
||||
// Web端登出
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.getWriter().write(new ObjectMapper().writeValueAsString(BaseResult.success()));
|
||||
})
|
||||
)
|
||||
|
||||
// 👇 6. 异常处理(认证失败 / 权限不足)
|
||||
// 异常处理
|
||||
.exceptionHandling(ex -> ex
|
||||
.authenticationEntryPoint((request, response, authException) -> {
|
||||
response.setStatus(401);
|
||||
response.getWriter().write("Unauthorized: " + authException.getMessage());
|
||||
response.setStatus(HttpStatus.UNAUTHORIZED.value());
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.getWriter().write(new ObjectMapper().writeValueAsString(
|
||||
BaseResult.error(HttpStatus.UNAUTHORIZED.value(), "未认证,请先登录")));
|
||||
})
|
||||
.accessDeniedHandler((request, response, accessDeniedException) -> {
|
||||
response.setStatus(403);
|
||||
response.getWriter().write("Forbidden: " + accessDeniedException.getMessage());
|
||||
response.setStatus(HttpStatus.FORBIDDEN.value());
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.getWriter().write(new ObjectMapper().writeValueAsString(
|
||||
BaseResult.error(HttpStatus.FORBIDDEN.value(), "无权访问")));
|
||||
})
|
||||
);
|
||||
|
||||
// 添加JWT过滤器(在UsernamePasswordAuthenticationFilter之前)
|
||||
// 这样JWT请求可以绕过Session认证,直接通过Token认证
|
||||
http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
|
||||
|
||||
return http.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SessionRegistry sessionRegistry() {
|
||||
return new SessionRegistryImpl();
|
||||
public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
|
||||
return config.getAuthenticationManager();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ConcurrentSessionFilter concurrentSessionFilter(SessionRegistry sessionRegistry) {
|
||||
return new ConcurrentSessionFilter(sessionRegistry);
|
||||
}
|
||||
|
||||
// 👇 提供 CORS 配置(生产环境请严格限制 origin)
|
||||
// 👇 提供 CORS 配置
|
||||
@Bean
|
||||
@Primary
|
||||
public CorsConfigurationSource corsConfigurationSource() {
|
||||
CorsConfiguration configuration = new CorsConfiguration();
|
||||
|
||||
// ✅ 允许的前端 origin(必须是具体地址,不能 *)
|
||||
// 允许的前端 origin
|
||||
configuration.setAllowedOriginPatterns(List.of("http://localhost:*", "http://127.0.0.1:*"));
|
||||
// ⚠️ 注意:Spring Boot 2.4+ 用 allowedOriginPatterns 支持通配符
|
||||
|
||||
// ✅ 允许凭证(Cookie)
|
||||
// 允许凭证(Cookie)
|
||||
configuration.setAllowCredentials(true);
|
||||
|
||||
// 允许的方法和头
|
||||
@@ -130,27 +153,4 @@ public class SecurityConfig {
|
||||
source.registerCorsConfiguration("/**", configuration);
|
||||
return source;
|
||||
}
|
||||
|
||||
// 👇 密码编码器(必须)
|
||||
// @Bean
|
||||
// public PasswordEncoder passwordEncoder() {
|
||||
// return md5PasswordEncoder;
|
||||
// }
|
||||
|
||||
// 👇 AuthenticationProvider(用于 DaoAuthenticationProvider)
|
||||
// @Bean
|
||||
// public AuthenticationProvider authenticationProvider() {
|
||||
// DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
|
||||
// authProvider.setUserDetailsService(userDetailsService);
|
||||
// authProvider.setPasswordEncoder(passwordEncoder());
|
||||
// return authProvider;
|
||||
// }
|
||||
|
||||
// 👇 AuthenticationManager(用于登录时 authenticate)
|
||||
// @Bean
|
||||
// public AuthenticationManager authenticationManager(
|
||||
// org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration config)
|
||||
// throws Exception {
|
||||
// return config.getAuthenticationManager();
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -3,7 +3,28 @@ package com.niuan.erp.module.sys.mapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.niuan.erp.module.sys.entity.SysUser;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface SysUserMapper extends BaseMapper<SysUser> {
|
||||
|
||||
/**
|
||||
* 根据角色ID查询用户ID列表
|
||||
*/
|
||||
@Select("SELECT DISTINCT ur.UserId FROM yy_usersrolemapping ur WHERE ur.RoleId = #{roleId}")
|
||||
List<Long> selectUserIdsByRoleId(@Param("roleId") Long roleId);
|
||||
|
||||
/**
|
||||
* 根据权限ID查询用户ID列表
|
||||
*/
|
||||
@Select("""
|
||||
SELECT DISTINCT ur.UserId
|
||||
FROM yy_usersrolemapping ur
|
||||
INNER JOIN yy_rolepermission rp ON ur.RoleId = rp.RoleId
|
||||
WHERE rp.PermissionId = #{permissionId}
|
||||
""")
|
||||
List<Long> selectUserIdsByPermissionId(@Param("permissionId") Long permissionId);
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package com.niuan.erp.module.sys.service;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.niuan.erp.common.base.BasePageReqParams;
|
||||
import com.niuan.erp.common.base.LoginUser;
|
||||
import com.niuan.erp.module.sys.controller.dto.SysUserDto;
|
||||
import com.niuan.erp.module.sys.entity.SysUser;
|
||||
|
||||
@@ -21,4 +22,19 @@ public interface SysUserService {
|
||||
void deleteBatch(List<Long> ids);
|
||||
|
||||
void setStatus(Long id, Integer status);
|
||||
|
||||
/**
|
||||
* 根据用户ID加载用户信息
|
||||
*/
|
||||
LoginUser loadUserById(Long userId);
|
||||
|
||||
/**
|
||||
* 根据角色ID查询用户ID列表
|
||||
*/
|
||||
List<Long> getUserIdsByRoleId(Long roleId);
|
||||
|
||||
/**
|
||||
* 根据权限ID查询用户ID列表
|
||||
*/
|
||||
List<Long> getUserIdsByPermissionId(Long permissionId);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.niuan.erp.common.base.BasePageReqParams;
|
||||
import com.niuan.erp.common.security.TokenService;
|
||||
import com.niuan.erp.common.utils.SecurityUtils;
|
||||
import com.niuan.erp.module.sys.controller.dto.SysRoleDto;
|
||||
import com.niuan.erp.module.sys.controller.dto.SysRoleSelectDto;
|
||||
@@ -15,6 +16,7 @@ import com.niuan.erp.module.sys.mapper.RolePermissionMapper;
|
||||
import com.niuan.erp.module.sys.mapper.SysPermissionMapper;
|
||||
import com.niuan.erp.module.sys.mapper.SysRoleMapper;
|
||||
import com.niuan.erp.module.sys.service.SysRoleService;
|
||||
import com.niuan.erp.module.sys.service.SysUserService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -34,6 +36,10 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
||||
|
||||
private final RolePermissionMapper rolePermissionMapper;
|
||||
|
||||
private final TokenService tokenService;
|
||||
|
||||
private final SysUserService sysUserService;
|
||||
|
||||
@Override
|
||||
public IPage<SysRoleDto> getSysRolePage(BasePageReqParams dto, LambdaQueryWrapper<SysRole> wrapper) {
|
||||
IPage<SysRole> result = this.baseMapper.selectPage(new Page<>(dto.page(), dto.pageSize()), wrapper);
|
||||
@@ -87,15 +93,34 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
||||
// 使用循环单条插入,避免无主键实体使用批量 insert 方法的问题
|
||||
newPermissions.forEach(rolePermissionMapper::insert);
|
||||
}
|
||||
// 角色修改后,踢掉所有拥有该角色的用户
|
||||
List<Long> userIds = sysUserService.getUserIdsByRoleId(entity.getId());
|
||||
if (userIds != null && !userIds.isEmpty()) {
|
||||
userIds.forEach(tokenService::removeAllUserTokens);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteSysRole(Long id) {
|
||||
// 角色删除前,踢掉所有拥有该角色的用户
|
||||
List<Long> userIds = sysUserService.getUserIdsByRoleId(id);
|
||||
if (userIds != null && !userIds.isEmpty()) {
|
||||
userIds.forEach(tokenService::removeAllUserTokens);
|
||||
}
|
||||
this.baseMapper.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteBatch(List<Long> ids) {
|
||||
if (ids != null && !ids.isEmpty()) {
|
||||
// 批量删除前,踢掉所有拥有这些角色的用户
|
||||
for (Long roleId : ids) {
|
||||
List<Long> userIds = sysUserService.getUserIdsByRoleId(roleId);
|
||||
if (userIds != null && !userIds.isEmpty()) {
|
||||
userIds.forEach(tokenService::removeAllUserTokens);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.baseMapper.deleteByIds(ids);
|
||||
}
|
||||
|
||||
@@ -104,6 +129,11 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
||||
SysRole entity = this.baseMapper.selectById(id);
|
||||
entity.setStatus(status);
|
||||
this.baseMapper.updateById(entity);
|
||||
// 角色状态修改后,踢掉所有拥有该角色的用户
|
||||
List<Long> userIds = sysUserService.getUserIdsByRoleId(id);
|
||||
if (userIds != null && !userIds.isEmpty()) {
|
||||
userIds.forEach(tokenService::removeAllUserTokens);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -5,18 +5,24 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.niuan.erp.common.base.BasePageReqParams;
|
||||
import com.niuan.erp.common.base.LoginUser;
|
||||
import com.niuan.erp.common.exception.BusinessException;
|
||||
import com.niuan.erp.common.security.TokenService;
|
||||
import com.niuan.erp.common.utils.SecurityUtils;
|
||||
import com.niuan.erp.module.sys.controller.dto.SysUserDto;
|
||||
import com.niuan.erp.module.sys.converter.SysUserConverter;
|
||||
import com.niuan.erp.module.sys.entity.SysPermission;
|
||||
import com.niuan.erp.module.sys.entity.SysRole;
|
||||
import com.niuan.erp.module.sys.entity.SysUser;
|
||||
import com.niuan.erp.module.sys.entity.UserRole;
|
||||
import com.niuan.erp.module.sys.mapper.SysPermissionMapper;
|
||||
import com.niuan.erp.module.sys.mapper.SysRoleMapper;
|
||||
import com.niuan.erp.module.sys.mapper.SysUserMapper;
|
||||
import com.niuan.erp.module.sys.mapper.UserRoleMapper;
|
||||
import com.niuan.erp.module.sys.service.SysUserService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -38,6 +44,10 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
|
||||
private final SysRoleMapper sysRoleMapper;
|
||||
|
||||
private final SysPermissionMapper sysPermissionMapper;
|
||||
|
||||
private final TokenService tokenService;
|
||||
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
|
||||
@Override
|
||||
@@ -175,10 +185,16 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
|
||||
// 更新用户角色关联
|
||||
updateUserRoles(id, dto.roleIds());
|
||||
|
||||
// 用户修改后,踢掉该用户
|
||||
tokenService.removeAllUserTokens(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteUser(Long id) {
|
||||
// 用户删除前,踢掉该用户
|
||||
tokenService.removeAllUserTokens(id);
|
||||
|
||||
// 删除用户角色关联
|
||||
LambdaQueryWrapper<UserRole> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(UserRole::getUserId, id);
|
||||
@@ -194,6 +210,9 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
return;
|
||||
}
|
||||
|
||||
// 批量删除前,踢掉这些用户
|
||||
ids.forEach(tokenService::removeAllUserTokens);
|
||||
|
||||
// 删除用户角色关联
|
||||
LambdaQueryWrapper<UserRole> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.in(UserRole::getUserId, ids);
|
||||
@@ -218,6 +237,9 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
updateUser.setUpdateDate(LocalDateTime.now());
|
||||
|
||||
this.baseMapper.updateById(updateUser);
|
||||
|
||||
// 用户状态修改后,踢掉该用户
|
||||
tokenService.removeAllUserTokens(id);
|
||||
}
|
||||
|
||||
private void checkLoginNameExists(String loginName, Long excludeId) {
|
||||
@@ -258,4 +280,35 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
// 保存新的角色关联
|
||||
saveUserRoles(userId, roleIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoginUser loadUserById(Long userId) {
|
||||
SysUser user = this.baseMapper.selectById(userId);
|
||||
if (user == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<SysRole> roleList = sysRoleMapper.selectByUserId(userId);
|
||||
List<SysPermission> permissionList = sysPermissionMapper.selectByUserId(userId);
|
||||
List<GrantedAuthority> authorities = permissionList.stream()
|
||||
.filter(p -> StringUtils.hasText(p.getPermissionCode()))
|
||||
.map(p -> new SimpleGrantedAuthority(p.getPermissionCode()))
|
||||
.collect(Collectors.toUnmodifiableList());
|
||||
|
||||
return LoginUser.builder()
|
||||
.user(user)
|
||||
.roleList(roleList)
|
||||
.authorities(authorities)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> getUserIdsByRoleId(Long roleId) {
|
||||
return this.baseMapper.selectUserIdsByRoleId(roleId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> getUserIdsByPermissionId(Long permissionId) {
|
||||
return this.baseMapper.selectUserIdsByPermissionId(permissionId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,24 @@ spring:
|
||||
url: jdbc:mysql://localhost:3306/ai
|
||||
username: steven
|
||||
password: 781203
|
||||
data:
|
||||
redis:
|
||||
host: localhost
|
||||
port: 6379
|
||||
password:
|
||||
database: 0
|
||||
lettuce:
|
||||
pool:
|
||||
max-active: 8
|
||||
max-idle: 8
|
||||
min-idle: 0
|
||||
max-wait: 1000ms
|
||||
|
||||
# jwt配置
|
||||
jwt:
|
||||
secret: your-256-bit-secret-key-here-must-be-at-least-32-characters
|
||||
expiration: 86400000
|
||||
refresh-expiration: 604800000
|
||||
|
||||
# mybatis 设置
|
||||
mybatis-plus:
|
||||
|
||||
Reference in New Issue
Block a user