后端基础框架

This commit is contained in:
2026-02-25 09:56:35 +08:00
commit b964b54fc6
146 changed files with 6919 additions and 0 deletions
@@ -0,0 +1,110 @@
package oailab.com.apistart.interceptor;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import oailab.com.apiservice.annotation.PassToken;
import oailab.com.apiservice.constants.LoginConstants;
import oailab.com.apiservice.enums.sys.ErrorCodeEnum;
import oailab.com.apiservice.exception.BizException;
import oailab.com.apiservice.mybatis.entity.sys.TenantAccount;
import oailab.com.apiservice.mybatis.service.sys.TenantAccountService;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import java.lang.reflect.Method;
/**
* Token validation interceptor.
*
* @author Benny Deng
* @version 1.0
* @see <a href="http://www.bianmaren.com">Benny Deng</a>
* @since 6/17/24 PM11:19
**/
@Slf4j
@Component("sysTokenInterceptor")
public class SysTokenInterceptor implements HandlerInterceptor {
@Resource
private TenantAccountService tenantAccountService;
@Override
public boolean preHandle(HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler) {
// 从 http 请求头中取出 token
String token = request.getHeader(LoginConstants.LOGIN_AUTHORIZATION);
// 如果不是映射到方法直接通过
if (!(handler instanceof HandlerMethod handlerMethod)) {
return true;
}
Method method = handlerMethod.getMethod();
// 检查是否有 @PassToken 注释,有则跳过认证
if (method.isAnnotationPresent(PassToken.class)) {
PassToken passToken = method.getAnnotation(PassToken.class);
if (passToken.required()) {
return true;
}
}
// 无token
if (token == null) {
throw new BizException(ErrorCodeEnum.TokenIsNull);
}
token = extractBearerToken(token);
// 获取 token 中的 user account
String account;
JWT jwt = JWTUtil.parseToken(token);
account = jwt.getPayload("account").toString();
TenantAccount tenantAccount = tenantAccountService.getByAccount(account);
if (null == tenantAccount) {
throw new BizException(ErrorCodeEnum.AccountDoesNotExist);
}
// 验证 token
if (!JWTUtil.verify(token, tenantAccount.getPassword().getBytes())) {
throw new BizException(ErrorCodeEnum.AuthTokenInvalid);
}
// 将提取的account,放入请求
request.setAttribute(LoginConstants.SYS_LOGIN_USER_ACCOUNT, account);
return true;
}
/**
* Remove "Bearer " prefix
*
* @param authorizationHeader 授权码
*/
private static String extractBearerToken(String authorizationHeader) {
if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
// Remove "Bearer " prefix
return authorizationHeader.substring(7);
}
return null;
}
@Override
public void postHandle(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler, ModelAndView modelAndView) {
}
@Override
public void afterCompletion(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler, Exception ex) {
}
}
@@ -0,0 +1,111 @@
package oailab.com.apistart.interceptor;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import oailab.com.apiservice.annotation.PassToken;
import oailab.com.apiservice.constants.LoginConstants;
import oailab.com.apiservice.enums.sys.ErrorCodeEnum;
import oailab.com.apiservice.exception.BizException;
import oailab.com.apiservice.mybatis.entity.workspace.EndUsers;
import oailab.com.apiservice.mybatis.service.workspace.EndUsersService;
import oailab.com.apiservice.service.PassportBusinessService;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import java.lang.reflect.Method;
import java.util.Map;
/**
* Token validation interceptor.
*
* @author Benny Deng
* @version 1.0
* @see <a href="http://www.bianmaren.com">Benny Deng</a>
* @since 6/17/24 PM11:19
**/
@Slf4j
@Component("webTokenInterceptor")
public class WebTokenInterceptor implements HandlerInterceptor {
@Resource
private PassportBusinessService passportBusinessService;
@Resource
private EndUsersService endUsersService;
@Override
public boolean preHandle(HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler) {
// 从 http 请求头中取出 token
String token = request.getHeader(LoginConstants.LOGIN_AUTHORIZATION);
// 如果不是映射到方法直接通过
if (!(handler instanceof HandlerMethod handlerMethod)) {
return true;
}
Method method = handlerMethod.getMethod();
// 检查是否有 @PassToken 注释,有则跳过认证
if (method.isAnnotationPresent(PassToken.class)) {
PassToken passToken = method.getAnnotation(PassToken.class);
if (passToken.required()) {
return true;
}
}
// 无token
if (token == null) {
throw new BizException(ErrorCodeEnum.TokenIsNull);
}
token = extractBearerToken(token);
Map<String, Object> payload = passportBusinessService.parse(token);
String endUserId = (String) payload.get("endUserId");
EndUsers endUser = endUsersService.getById(endUserId);
if (null == endUser) {
throw new BizException(ErrorCodeEnum.AccountDoesNotExist);
}
// 验证 token
if (!passportBusinessService.verify(token)) {
throw new BizException(ErrorCodeEnum.AuthTokenInvalid);
}
// 将提取的account,放入请求
request.setAttribute(LoginConstants.WEB_LOGIN_USER_ACCOUNT, endUserId);
return true;
}
/**
* Remove "Bearer " prefix
*
* @param authorizationHeader 授权码
*/
private static String extractBearerToken(String authorizationHeader) {
if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
// Remove "Bearer " prefix
return authorizationHeader.substring(7);
}
return null;
}
@Override
public void postHandle(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler, ModelAndView modelAndView) {
}
@Override
public void afterCompletion(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler, Exception ex) {
}
}