java 後端 控制跨域問題

林财钦發表於2024-08-02

@Component
public class UserLoginInterceptor implements HandlerInterceptor {
	private static final Logger logger = LoggerFactory.getLogger(UserLoginInterceptor.class);
	
	@Value("${zyplayer.doc.manage.originDomainRegex:}")
	private String originDomainRegex;
	
	private final ThreadLocal<Long> startTimeThreadLocal = new ThreadLocal<>();
	
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object arg2, Exception arg3) {
		Long startTime = startTimeThreadLocal.get();
		startTime = Optional.ofNullable(startTime).orElse(System.currentTimeMillis());
		long totalTime = System.currentTimeMillis() - startTime;
		String clientIP = ServletUtil.getClientIP(request);
		logger.info("IP:{},總耗時:{}ms,URI:{}", clientIP, totalTime, request.getRequestURI());
		startTimeThreadLocal.remove();
		// 清理使用者資訊
		DocUserUtil.clean();
	}
	
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
	}
	
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
		startTimeThreadLocal.set(System.currentTimeMillis());
		// 指定域名可跨域訪問
		if (StringUtils.isNotBlank(originDomainRegex)) {
			String origin = request.getHeader("Origin");
			if (StringUtils.isNotBlank(origin) && origin.toLowerCase().matches(originDomainRegex)) {
				response.setHeader("Access-Control-Allow-Origin", origin); // 允許訪問的域
				response.setHeader("Access-Control-Allow-Methods", "HEAD,GET,POST,PUT,DELETE");// 允許GET、POST的外域請求
				response.setHeader("Access-Control-Allow-Credentials", "true"); // 允許請求帶cookie到伺服器
				response.setContentType("application/json; charset=utf-8"); // 設定JSON格式標準輸出、及編碼
			}
		}
		if (!(handler instanceof HandlerMethod)) {
			return true;
		}
		// 清理使用者資訊
		DocUserUtil.clean();
		// 設定token
		Cookie cookie = ServletUtil.getCookie(request, HttpConst.ACCESS_TOKEN);
		String accessToken = (cookie == null) ? null : cookie.getValue();
		DocUserUtil.setAccessToken(accessToken);
		AuthMan authMan = ((HandlerMethod) handler).getMethod().getAnnotation(AuthMan.class);
		if (authMan == null) {
			authMan = ((HandlerMethod) handler).getMethod().getDeclaringClass().getAnnotation(AuthMan.class);
			if (authMan == null) {
				return true;
			}
		}
		DocUserDetails currentUser = DocUserUtil.getCurrentUser();
		if (currentUser == null) {
			String reason = "你訪問的內容需要登入,請登入後再試";
			DocResponseJson.failure(HttpConst.TOKEN_TIMEOUT, reason).send(response);
			return false;
		}
		// 判斷許可權是否足夠
		boolean haveAuth = DocUserUtil.haveAuth(authMan.value());
		if (haveAuth) {
			return true;
		}
		String reasonStr = "沒有操作許可權,請聯絡管理員";
		DocResponseJson.warn(reasonStr).send(response);
		return false;
	}
	
}

java 後端 控制跨域問題

# 系統根域名,除錯UI時需要使用,同時需要在host檔案裡配置:127.0.0.1 local.zyplayer.com
#originDomainRegex: .*\.zyplayer\.com(:\d+|)$
originDomainRegex: .*\.zyplayer\.com(:\d+|)$

相關文章