如何通过 HTTP 连接使用 Set-Cookie 标头发送 HTTP Cookie?

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

我正在使用 Java Spring 框架和 Spring Security 开发 Web 应用程序的后端。我正在尝试使用 JWT 创建一个登录系统,方法是使用 Set-Cookie 标头将 JWT 访问令牌作为 cookie 从服务器发送到客户端。

当我用 Postman 在 localhost 上测试时,我似乎没有问题。然而,当尝试将 cookie 发送到另一台电脑上的客户端时,Set-Cookie 标头似乎被客户端拒绝。

这是从客户端接收登录请求的逻辑,如果登录有效,则返回 JWT 访问令牌:

@PostMapping("/login") public ResponseEntity<?> authenticate(HttpServletRequest request, HttpServletResponse response, @RequestBody AuthRequestDTO requestDTO){ // Verify the client's login (username and password) AuthDTO responseDTO = authService.authenticate(requestDTO); // Set JWT access token if the client's login details are valid ResponseCookie cookieAccessToken = ResponseCookie.from("accessToken", responseDTO.getAccessToken()) .maxAge(Duration.ofMinutes(5)) .domain(request.getRemoteAddr()) .sameSite("Lax") .secure(false) .httpOnly(true) .build(); // Add access token as "Set-Cookie" key-value in HTTP response header. response.addHeader(HttpHeaders.SET_COOKIE, cookieAccessToken.toString()); log.info("Access Token Cookie : " + cookieAccessToken.toString()); return ResponseEntity.ok().body(null); }
我觉得重点是关于ResponseCookie方法。我尝试过更改许多方法选项,但无济于事。如果有人曾经通过 HTTP 连接(不是 HTTPS - 由于代码处于早期开发阶段)发送 cookie,我将不胜感激。

作为参考,这是我的 Spring Security 配置设置(AUTH_WHITELIST 允许访问登录 API,而无需访问令牌,jwtAuthenticationFilter 是我的 JWT 自定义实现的 spring bean 组件):

@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception{ http.csrf((csrf) -> csrf.disable()) .headers((header)->header.frameOptions((fo)->fo.sameOrigin())) .authorizeHttpRequests((authorize) -> authorize .requestMatchers(AUTH_WHITELIST).permitAll() .requestMatchers("/api/admin").hasAnyRole(ADMIN_MAIN.name(), ADMIN_SUB.name()) .requestMatchers("/api/file").hasAnyRole(ADMIN_MAIN.name(), ADMIN_SUB.name()) .requestMatchers("/**").hasAnyRole(ADMIN_MAIN.name(), ADMIN_SUB.name(), USER_ENTERPRISE.name(), USER_INDIVIDUAL.name(), VISITOR.name()) .anyRequest().authenticated()); http.sessionManagement((sessionManagement) -> sessionManagement .sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .authenticationProvider(authenticationProvider) .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); http.logout((logout) -> logout.logoutUrl("/api/auth/logout").addLogoutHandler(logoutHandler) .logoutSuccessHandler((request, response, authentication) -> SecurityContextHolder.clearContext())); return http.build(); }
我尝试从多个客户端访问登录 API。我尝试从另一台电脑访问 Google Chrome、Mozilla Firefox 和 Postman 上的登录 API(即与服务器不同的 IP 地址)。

编辑:我确实在单独的文件中配置了 CORS。

@Override public void addCorsMappings(CorsRegistry registry){ // addMapping configures the URL patterns to which the CORS configuration applies. In this case, it is set to apply to all paths ("/**"). // allowedOrigins method sets the list of origins (domains) allowed to access resources on the server. In this case, the server accepts requests from any domain ("*"). // allowedMethods method sets the HTTP methods that are allowed for cross-origin requests. registry.addMapping("/**") .allowedOriginPatterns("*") .allowCredentials(true) .allowedMethods("GET", "POST", "PUT", "DELETE"); }
    
java spring http security web
1个回答
0
投票
几件事:

    检查 CORS 配置:跨域资源共享 (CORS) 可能会阻止客户端表单接受来自服务器的 cookie。确保您的 CORS 配置允许凭证 (cookie) 与请求一起发送。您可以通过在 Spring Security 配置中配置 CORS 来做到这一点:
@Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurer() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") .allowedMethods("GET", "POST", "PUT", "DELETE") .allowCredentials(true) // Allow cookies .maxAge(3600); } }; }

    检查您的 Cookie 域 为 cookie 指定的域可能无效> 您可以将域显式设置为您的应用程序域或
  1. request.getRemoteAddr()
     进行测试,而不是使用 
    localhost
     
ResponseCookie cookieAccessToken = ResponseCookie.from("accessToken", responseDTO.getAccessToken()) .maxAge(Duration.ofMinutes(5)) .domain("yourdomain.com") // Set your domain here .path("/") // Set the path if necessary .sameSite("Lax") .secure(false) .httpOnly(true) .build();
    
© www.soinside.com 2019 - 2024. All rights reserved.