set-cookie 不与 http 请求标头一起发回

Posted

技术标签:

【中文标题】set-cookie 不与 http 请求标头一起发回【英文标题】:set-cookie is not sent back with http request header 【发布时间】:2020-10-27 04:25:57 【问题描述】:

已经花了一天时间寻找可行的解决方案。 我使用 Spring 作为后端,使用 Angular 作为前端。 我使用 JWT 来管理身份验证。 我想在用户登录后将 JWT 令牌存储在响应 cookie 中。 然后随每个请求自动发回。 当用户在 spring 端成功登录时,我在响应中添加了一个 JWT cookie

    @PostMapping("/getLogin")
    public ResponseEntity<LoginModel> getLogin(@RequestBody LoginFour loginFour, HttpServletRequest request,
                                               HttpServletResponse response) 
        final LoginModel loginModel = userInformationService.getLoged(loginFour,
                loginFour.getIpAdress(), loginFour.getTimeZone());

        Cookie jwtCookie = new Cookie("JWT_TOKEN", loginModel.getJwt());
        jwtCookie.setMaxAge(15 * 60 * 1000);
        jwtCookie.setHttpOnly(false);
        jwtCookie.setSecure(false);
        response.addCookie(jwtCookie);

        return new ResponseEntity<>(loginModel, HttpStatus.OK);
    

在浏览器中,当我检查网络选项卡时,我可以在响应标头中看到 cookie

那么当我发送另一个请求时,cookie 不会在请求标头中发回

使用 angular 存储的其他 cookie 以请求结束,但不是从第一个请求的响应标头提供的 jet

这是我的 Angular HTTP 拦截器

@Injectable()
export class HttpInterceptorService implements HttpInterceptor 

    constructor(private router: Router) 
    

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> 
        console.log(req.url);
        const reqClone = this.addHeader(req);

        return next.handle(reqClone).pipe(
            catchError((error: HttpErrorResponse) => 
                if (error.status >= 200 && error.status < 300) 
                    return this.handleTextResponse(error);
                 else if (error.status == 403) 
                    localStorage.clear();
                    this.router.navigate(['/auth/login']);
                
                return this.handleError(error);
            )
        );
    

    private addHeader(req: HttpRequest<any>) 
        return req.clone(
            setHeaders: 
                'Content-Type': 'application/json'
            ,
            withCredentials: true
        );
    

这是我的 spring 安全配置

@EnableWebSecurity
public class SecurityConfigurer extends WebSecurityConfigurerAdapter 

    public static final String[] AUTHORIZED_PATHS = new String[]
            "/login/getLogin",
            "/angularBeanLogin/resetPasswrod",
            "/angularBeanSignup/setUser",
            "/angularBeanTest/getUserSettingAccess",
            "/angularBeanTest/getUserRole",
            "/login/getAllPermitForChart"
    ;

    private final UserDetailsServiceImpl userDetailService;
    private final JWTRequestFilter jwtRequestFilter;

    public SecurityConfigurer(UserDetailsServiceImpl userDetailService, JWTRequestFilter jwtRequestFilter) 
        this.userDetailService = userDetailService;
        this.jwtRequestFilter = jwtRequestFilter;
    

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception 
        auth.userDetailsService(userDetailService)
                .passwordEncoder(new PasswordEncoderImpl());
    

    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http.cors().disable()
                .csrf().disable()
                .authorizeRequests().antMatchers(AUTHORIZED_PATHS).permitAll()
                .anyRequest().authenticated()
                .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and().addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
    

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception 
        return super.authenticationManagerBean();
    


不明白 set-cookie 没有与其他 cookie 一起发送到服务器的原因

使用 angular 5.0.5 和 spring boot 2.0.2.RELEASE

【问题讨论】:

【参考方案1】:

我已使用以下代码在每个请求中添加 cookie...

import  Observable  from 'rxjs/Observable';
import  HttpInterceptor, HttpRequest, HttpHandler, HttpEvent  from '@angular/common/http';
import  Injectable  from '@angular/core';

@Injectable()
export class AuthInterceptor implements HttpInterceptor 
  constructor() 

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> 
    request = request.clone(
      withCredentials: true
  );
  return next.handle(request);
  

并添加到 app.module.ts 的 providers 数组中,如下所示。

import  AuthInterceptor  from './services/auth.interceptor';
import  HTTP_INTERCEPTORS  from '@angular/common/http';
import  HttpClientModule  from '@angular/common/http';
imports: [
    BrowserModule,HttpClientModule,FormsModule
  ],

providers: [
    
    provide: HTTP_INTERCEPTORS,
    useClass: AuthInterceptor,
    multi: true,
    
]

【讨论】:

我做了同样的事情并且已经发布了我的拦截器,存储的cookies在请求头中发送,我可以在后端找到它们没有问题,只有来自服务器发送的set-cookie它们在响应头中丢失了

以上是关于set-cookie 不与 http 请求标头一起发回的主要内容,如果未能解决你的问题,请参考以下文章

即使响应包含 ajax 请求的“Set-Cookie”标头,cookie 也不会存储在浏览器中

即使响应包含ajax请求的“Set-Cookie”标头,cookie也不会存储在浏览器中

未设置 Set-Cookie 标头中的 Cookie

从打字稿中的 Set-Cookie 标头中获取 jwt 值

Chrome 获取 Set-cookie 标头但未将其放入新请求中

如何在 WPF 应用程序中 SOAP 客户端的“Set-Cookie”标头响应的新请求中设置“Cookie”标头