fix(auth): move admin session to HttpOnly cookies

This commit is contained in:
Kroytz committed 2026-07-19 00:25:39 +08:00
1 parent 0d2165cf80
commit 17b2ba49a8
39 files changed
+191 -219

No files matched your search

@@ -24,19 +24,28 @@ import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseCookie;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.WebUtils;
import jakarta.annotation.Resource;
import jakarta.annotation.security.PermitAll;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import java.time.Duration;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import static co.yixiang.yshop.framework.common.exception.enums.GlobalErrorCodeConstants.UNAUTHORIZED;
import static co.yixiang.yshop.framework.common.exception.util.ServiceExceptionUtil.exception;
import static co.yixiang.yshop.framework.common.pojo.CommonResult.success;
import static co.yixiang.yshop.framework.common.util.collection.CollectionUtils.convertSet;
import static co.yixiang.yshop.framework.security.core.util.SecurityFrameworkUtils.ACCESS_TOKEN_COOKIE;
import static co.yixiang.yshop.framework.security.core.util.SecurityFrameworkUtils.REFRESH_TOKEN_COOKIE;
import static co.yixiang.yshop.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
@Tag(name = "管理后台 - 认证")
@@ -69,15 +78,25 @@ public class AuthController {
return success(authService.login(reqVO));
}
@PostMapping("/login-cookie")
@PermitAll
@Operation(summary = "使用账号密码登录(HttpOnly Cookie)")
public CommonResult<Boolean> loginCookie(@RequestBody @Valid AuthLoginReqVO reqVO,
HttpServletResponse response) {
writeTokenCookies(response, authService.login(reqVO));
return success(true);
}
@PostMapping("/logout")
@PermitAll
@Operation(summary = "登出系统")
public CommonResult<Boolean> logout(HttpServletRequest request) {
public CommonResult<Boolean> logout(HttpServletRequest request, HttpServletResponse response) {
String token = SecurityFrameworkUtils.obtainAuthorization(request,
securityProperties.getTokenHeader(), securityProperties.getTokenParameter());
if (StrUtil.isNotBlank(token)) {
authService.logout(token, LoginLogTypeEnum.LOGOUT_SELF.getType());
}
clearTokenCookies(response);
return success(true);
}
@@ -89,6 +108,18 @@ public class AuthController {
return success(authService.refreshToken(refreshToken));
}
@PostMapping("/refresh-token-cookie")
@PermitAll
@Operation(summary = "刷新令牌(HttpOnly Cookie)")
public CommonResult<Boolean> refreshTokenCookie(HttpServletRequest request, HttpServletResponse response) {
if (WebUtils.getCookie(request, REFRESH_TOKEN_COOKIE) == null) {
throw exception(UNAUTHORIZED);
}
writeTokenCookies(response,
authService.refreshToken(WebUtils.getCookie(request, REFRESH_TOKEN_COOKIE).getValue()));
return success(true);
}
@GetMapping("/get-permission-info")
@Operation(summary = "获取登录用户的权限信息")
public CommonResult<AuthPermissionInfoRespVO> getPermissionInfo() {
@@ -124,6 +155,15 @@ public class AuthController {
return success(authService.smsLogin(reqVO));
}
@PostMapping("/sms-login-cookie")
@PermitAll
@Operation(summary = "使用短信验证码登录(HttpOnly Cookie)")
public CommonResult<Boolean> smsLoginCookie(@RequestBody @Valid AuthSmsLoginReqVO reqVO,
HttpServletResponse response) {
writeTokenCookies(response, authService.smsLogin(reqVO));
return success(true);
}
@PostMapping("/send-sms-code")
@PermitAll
@Operation(summary = "发送手机验证码")
@@ -154,4 +194,28 @@ public class AuthController {
return success(authService.socialLogin(reqVO));
}
@PostMapping("/social-login-cookie")
@PermitAll
@Operation(summary = "社交快捷登录(HttpOnly Cookie)")
public CommonResult<Boolean> socialQuickLoginCookie(@RequestBody @Valid AuthSocialLoginReqVO reqVO,
HttpServletResponse response) {
writeTokenCookies(response, authService.socialLogin(reqVO));
return success(true);
}
private void writeTokenCookies(HttpServletResponse response, AuthLoginRespVO token) {
response.addHeader(HttpHeaders.SET_COOKIE, tokenCookie(ACCESS_TOKEN_COOKIE, token.getAccessToken()).toString());
response.addHeader(HttpHeaders.SET_COOKIE, tokenCookie(REFRESH_TOKEN_COOKIE, token.getRefreshToken()).toString());
}
private void clearTokenCookies(HttpServletResponse response) {
response.addHeader(HttpHeaders.SET_COOKIE, tokenCookie(ACCESS_TOKEN_COOKIE, "").maxAge(Duration.ZERO).toString());
response.addHeader(HttpHeaders.SET_COOKIE, tokenCookie(REFRESH_TOKEN_COOKIE, "").maxAge(Duration.ZERO).toString());
}
private ResponseCookie.ResponseCookieBuilder tokenCookie(String name, String value) {
return ResponseCookie.from(name, value).httpOnly(true).secure(securityProperties.getCookieSecure())
.sameSite("Strict").path("/");
}
}