auth-service/src/main/java/com/goi/erp/auth/AuthCookieService.java

110 lines
3.3 KiB
Java

package com.goi.erp.auth;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.Optional;
@Service
public class AuthCookieService {
public static final String AUTH_COOKIE_NAME = "AUTH_TOKEN";
public static final String REFRESH_COOKIE_NAME = "REFRESH_TOKEN";
@Value("${auth.cookie.secure:true}")
private boolean secure;
@Value("${auth.cookie.same-site:Lax}")
private String sameSite;
@Value("${auth.cookie.path:/}")
private String path;
// ===================== Access Token =====================
public void addAuthCookie(HttpServletResponse response, String jwt) {
addCookie(response, AUTH_COOKIE_NAME, jwt, -1);
}
public void clearAuthCookie(HttpServletResponse response) {
addCookie(response, AUTH_COOKIE_NAME, null, 0);
}
public Optional<String> extractJwt(HttpServletRequest request) {
return extractCookie(request, AUTH_COOKIE_NAME);
}
// ===================== Refresh Token =====================
public void addRefreshCookie(HttpServletResponse response, String refreshToken) {
addCookie(response, REFRESH_COOKIE_NAME, refreshToken, -1);
}
public void clearRefreshCookie(HttpServletResponse response) {
addCookie(response, REFRESH_COOKIE_NAME, null, 0);
}
public Optional<String> extractRefreshToken(HttpServletRequest request) {
return extractCookie(request, REFRESH_COOKIE_NAME);
}
// ===================== 내부 공통 =====================
private void addCookie(
HttpServletResponse response,
String name,
String value,
int maxAge
) {
Cookie cookie = new Cookie(name, value);
cookie.setHttpOnly(true);
cookie.setSecure(secure);
cookie.setPath(path);
cookie.setMaxAge(maxAge);
response.addCookie(cookie);
addSameSiteAttribute(response, cookie);
}
private Optional<String> extractCookie(HttpServletRequest request, String name) {
if (request.getCookies() == null) {
return Optional.empty();
}
return Arrays.stream(request.getCookies())
.filter(c -> name.equals(c.getName()))
.map(Cookie::getValue)
.filter(v -> v != null && !v.isBlank())
.findFirst();
}
/**
* SameSite 수동 세팅 (Servlet Cookie API 한계)
*/
private void addSameSiteAttribute(HttpServletResponse response, Cookie cookie) {
StringBuilder sb = new StringBuilder();
sb.append(cookie.getName()).append("=");
sb.append(cookie.getValue() == null ? "" : cookie.getValue());
sb.append("; Path=").append(cookie.getPath());
sb.append("; HttpOnly");
if (cookie.getSecure()) {
sb.append("; Secure");
}
if (sameSite != null && !sameSite.isBlank()) {
sb.append("; SameSite=").append(sameSite);
}
if (cookie.getMaxAge() == 0) {
sb.append("; Max-Age=0");
}
response.addHeader("Set-Cookie", sb.toString());
}
}