浏览器未将 cookie 发送到后端并首先完成设置

问题描述 投票:0回答:1

大家好,我试图使用仅 HTTP 的 cookie 来保护我的 Spring Boot 应用程序,从本地存储迁移,我遇到了一些甚至 chatGPT 也无法解决的问题:)

首先,这是我的 CookieUtil 类


import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletResponse;

public class CookieUtil {

    public static void create(HttpServletResponse httpServletResponse, String name, String value, Integer maxAge) {
        Cookie cookie = new Cookie(name, value);
        cookie.setSecure(false);
        cookie.setHttpOnly(true);
        cookie.setMaxAge(maxAge);
        cookie.setPath("/");
        cookie.setDomain("localhost");
        httpServletResponse.addCookie(cookie);
    }

    public static void clear(HttpServletResponse httpServletResponse, String name) {
        Cookie cookie = new Cookie(name, null);
        cookie.setPath("/");
        cookie.setHttpOnly(true);
        cookie.setMaxAge(0);
        httpServletResponse.addCookie(cookie);
    }
}

我尝试将 HttpOnly 设置为 false 以查看令牌是否在浏览器中设置,但仍然没有显示相同的内容,我知道当我设置为仅 HTTP 时它不应该显示 我知道 setSecure 只是为了本地开发

这是我的登录方法

   public AccessTokenResponse signIn(LoginDto loginDto) {

        AccessTokenResponse accessTokenResponse = authorizations.signIn(loginDto);
        String jwt= accessTokenResponse.getToken();
        int maxAge= (int)accessTokenResponse.getExpiresIn();
        CookieUtil.create(response, "accessToken", jwt, maxAge);
        return accessTokenResponse;
    }

我使用 keycloak 作为赔偿管理器,我得到了很好的令牌,如下图所示 这是请求标头,您可以看到设置的 cookie 就在那里,(当我登录时,浏览器中也有同样的事情,我得到了设置的 cookie 标头)

这就是它在开发工具中的样子

现在的问题是从 accessToken 获取员工 By Keycloak

@GetMapping("/employee")
    public ResponseEntity<EmployeeDto> getEmployeeByKeycloakId(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        String token = null;
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals("accessToken")) {
                    token = cookie.getValue();
                    break;
                }
            }
        }
        if (token == null) {
            return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
        }
        String userid= tokenService.getUserIdFromToken(token);
        return new ResponseEntity<>(
                employeeMapper.toEmployee(this.employeeUseCases.getByKeycloakId(userid)),
                HttpStatus.OK
        );
    }

如您所见,我正在尝试获取 cookie accessToken 来对其进行解码并获取 userId(顺便说一句,解码部分工作正常)此方法总是失败的原因是因为 cookie 始终为 null 意味着浏览器没有将它们发送到服务器

说到前面的代码,这是我的登录信息

 signIn(user: User, rememberMe: boolean): Observable<any> {

        return this._httpClient.post(`${this._apiUrl}/login`, user).pipe(
            switchMap((response: any) => {
                if (response.access_token) {   
                    if(rememberMe){
                        this._storageService.setItem('rememberMe', JSON.stringify(rememberMe));
                    }
                   
                }
                this._authenticated = true;
                return this._userService.get();
            })
        );
    }

这是应该添加令牌的标志部分

这就是获取员工的终点

 get(): any {

        return this._httpClient
            .get<User>(`${this._apiUrl}/employee`, { withCredentials: true })
            .pipe(
                tap((user) => {
                    console.log(user)
                    this._user.next(user);
                })
            );
    }

如你所见,我使用 withCredentials:true

说到cors,我的控制器中已经有了这个

@CrossOrigin(origins = "http://localhost:4200", allowCredentials = "true")
@RestController
@RequestMapping("/api/v1/employees")
public class EmployeeController 

@CrossOrigin(origins = "http://localhost:4200", allowCredentials = "true")
@RestController
@RequestMapping("/api/v1/auth")
public class AuthorisationController {

我感谢任何帮助

java angular spring-boot cookies
1个回答
0
投票

即使您正在进行本地开发,由于您是通过 https 访问您的网站,因此您应该将 Secure 标志设置为 true 以便发送 cookie。

© www.soinside.com 2019 - 2024. All rights reserved.