未在浏览器中创建响应标头中的 Set-Cookie - 使用 http POST

Posted

技术标签:

【中文标题】未在浏览器中创建响应标头中的 Set-Cookie - 使用 http POST【英文标题】:Set-Cookie in Response Header not being created in browser - Using http POST 【发布时间】:2022-02-16 22:30:19 【问题描述】:

我一直被与 cookie 相关的此类问题所困扰。

我的情况是这样的:

我的后端在服务器上 (localhst:12456) 我的 Angular 2 应用程序在另一台服务器 (localhost:5555) 上运行

我的后端只是一个 ASP.NET 应用程序,我正在尝试从 apiController 对用户进行身份验证。 api Controller 是这样的:

[System.Web.Mvc.HttpPost]
        public HttpResponseMessage HandleLogin([FromBody] LoginModel loginModel)
        
            if (!String.IsNullOrEmpty(loginModel.Username) && !String.IsNullOrEmpty(loginModel.Password))
            

                if (Members.Login(loginModel.Username, loginModel.Password))
                
                    var resp = Request.CreateResponse<UserAuthenticationModel>(
                         HttpStatusCode.OK,
                        new UserAuthenticationModel()  IsAuthenticated = true
                    );

                    //create and set cookie in response
                    var cookie = new CookieHeaderValue("customCookie", "cookieVal");
                    cookie.Expires = DateTimeOffset.Now.AddDays(1);
                    cookie.Domain = Request.RequestUri.Host;
                    cookie.Path = "/";
                    resp.Headers.AddCookies(new CookieHeaderValue[]  cookie );

                    return resp;
                
            

            return Request.CreateResponse<UserAuthenticationModel>(
                  new UserAuthenticationModel()  IsAuthenticated = false 
            );
        

现在,在我的 Angular 应用中,我正在调用一个 http 帖子:

headers.append('Access-Control-Allow-Credentials', true);

    return this._http.post(this._globalVariables.BACKEND_API_HANDLE_LOGIN, loginModel, headers: headers)
                .map((response : Response) => response);

this._loginService.getLoginModel() 。订阅( loginModel => this._signInPageModel = loginModel, 错误 => 控制台日志(错误) ); 现在,在我的 api 控制器方法(HandleLogin)中,我有一个测试 cookie 和另一个用于 FormsAuthentication 的 cookie,当用户成功登录并返回到我的 Angular 应用程序时,不会创建任何 cookie。

现在,可以看到 cookie 以及我的响应标头的帖子:

我对此感到很困惑,并感谢任何帮助以成功获得登录过程。

提前谢谢你。

【问题讨论】:

你还有什么问题? 你找到问题了吗? 【参考方案1】:

我在同一个问题上浪费了一整天。我发现这些是重要的部分:

1.您需要在服务器上添加以下标头(替换为您的客户端主机地址)。 CORS 需要这些,因为您的两个站点使用不同的端口号。

Access-Control-Allow-Origin: http://localhost:5555
Access-Control-Allow-Credentials: true

对于 WebAPI,这意味着将以下内容放在 WebApiConfig.Register 的顶部:

var cors = new EnableCorsAttribute("http://localhost:5555", "*", "GET,POST");
cors.SupportsCredentials = true;
config.EnableCors(cors);

2。准确说明您如何设置 Cookie

看看这些:

response.Headers.AddCookies(new CookieHeaderValue[] 
 
  new CookieHeaderValue("WorkingCookie", cookieValue)  Path="/" , 
  new CookieHeaderValue("NotWorkingCookie", cookieValue) 
);

如果不指定路径,我无法让 CORS cookie 工作。此外,this SO answer 声称在生产环境中,您还需要指定域。我还没到那里,所以我现在只是记下它。

3.注意后端限制

据我所知,Web API 并不是真正的问题,但对于 php,多个 Set-Cookie 标头无法正常工作。我只能将列出的最后一个保留在客户端上。

4.在您的 HTTP 请求上使用 withCredentials*

这是我对您前面列出的电话的看法:

return this._http.post(this._globalVariables.BACKEND_API_HANDLE_LOGIN,
    loginModel, headers: headers, withCredentials: true)
    .map((response : Response) => response);

注意 withCredentials 作为选项的一部分传递。

这是您缺少的部分,绝对是关键。其他步骤是为了确保 cookie 由服务器正确发送并由浏览器持久保存,但 withCredentials 管理 whether the browser will include its cookies in the request header。

不过,您需要确保使用的是更新版本的 Angular;甚至一些 RC 版本完全忽略了withCredentials 选项,因此根本不能用于像这样的 CORS 调用。

最后说明 如果您要使用 cookie 创建 CORS 身份验证系统,则需要注意两件事:

    在 Web API 中标记您的会话 cookie HttpOnly,这样它就不会被注入的 javascript 篡改。 在服务器端生成并存储一个密钥,您在名为XSRF-TOKEN 的(非HttpOnly)cookie 中返回该密钥。在每次 API 调用中,将此存储的值与 Angular 将返回的 X-XSRF-TOKEN 标头的值进行比较。这是防止CSRF attacks 所必需的。

【讨论】:

以上是关于未在浏览器中创建响应标头中的 Set-Cookie - 使用 http POST的主要内容,如果未能解决你的问题,请参考以下文章

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

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

如果我们尝试设置之前安全的 cookie,浏览器会忽略 Set-Cookie 响应标头

在 AWS Cloudfront 源请求中返回带有 set-cookie 标头的响应

iOS 10.3 中的 ajax 响应中缺少 Set-Cookie 标头

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