如何使用aspnet core 6 web api在浏览器中设置cookie?

Boy*_*smo 8 c# cookies asp.net-web-api .net-6.0

我使用 Visual Studio 2022 创建了该项目,并选择了 aspnet core 6 Web api 模板。我正在尝试在浏览器中设置 cookie,但似乎我遗漏了一些内容,因为它没有在“网络” > “应用程序” > “Cookies”下设置任何内容

我的前端是一个反应应用程序。目前还没有额外的库。这是运行命令后的默认项目npx create-react-app <project-name>

我可以/weatherforecast毫无问题地调用端点。但由于某种原因,它没有设置cookie。

frontend call

const getData = async () => {
  await axios.get("/weatherforecast");
};
Run Code Online (Sandbox Code Playgroud)

WeatherForecastController.cs

public IActionResult Get()
{
  Response.Cookies.Append("myjwt", "ABCDE", new CookieOptions
  {
    Secure = true,
    HttpOnly = true,
    SameSite = SameSiteMode.None
  });

  return Ok();
}
Run Code Online (Sandbox Code Playgroud)

Program.cs

var builder = WebApplication.CreateBuilder(args);

const string AllowAllHeadersPolicy = "AllowAllPolicy";

builder.Services.AddCors(options =>
{
    options.AddPolicy(AllowAllHeadersPolicy,
        builder =>
        {
            builder
                .WithOrigins(new[] { "http://localhost:3000" })
                .AllowAnyMethod()
                .AllowAnyHeader()
                .AllowCredentials();
        });
});

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

app.UseCors(AllowAllHeadersPolicy);

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

Run Code Online (Sandbox Code Playgroud)

我想做的最终目标是将刷新令牌存储在 cookie 中HttpOnly=true

我尝试过的:

  • 我用失眠来测试终点。工作完美!也设置cookie。
  • 发现了这个问题,但没有明确的答案。

Mak*_*sym 9

下面的视图是您在技术上尝试做的事情:

在此输入图像描述

您可以通过多种方式做到这一点

选项 1:内置中间件

services.AddSession(options =>
    {
        options.Cookie.Name = ".AdventureWorks.Session";
        options.IdleTimeout = TimeSpan.FromSeconds(10);
        options.Cookie.IsEssential = true;
    });
Run Code Online (Sandbox Code Playgroud)

然后你必须指示使用中间件(这是你似乎缺少的东西)

app.UseSession();
Run Code Online (Sandbox Code Playgroud)

选项 2:手动指示您的 API 需要添加 cookie:

public HttpResponseMessage Get()
{
    var resp = new HttpResponseMessage();

    var cookie = new CookieHeaderValue("session-id", "12345");
    cookie.Expires = DateTimeOffset.Now.AddDays(1);
    cookie.Domain = Request.RequestUri.Host;
    cookie.Path = "/";

    resp.Headers.AddCookies(new CookieHeaderValue[] { cookie });
    return resp;
}
Run Code Online (Sandbox Code Playgroud)

Microsoft 提供了 MessageHandler(针对 ASP.Net)和 DelegatingHandler(针对 Core 中的 API 入站或出站连接 - 可以附加到 HttpClientFactory在 ASP.NET Core 5.0 Web API 中实现 DelegatingHandler 吗?)的示例。您还可以使用普通的中间件来交叉和更新请求/响应数据(示例在这里ASP .NET Core webapi set cookie in middleware

使用 DelegatingHandler 的伪代码示例

using System;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;

public class SessionIdHandler : DelegatingHandler
{
    public static string SessionIdToken = "session-id";

    async protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    {
        string sessionId;

        // Try to get the session ID from the request; otherwise create a new ID.
        var cookie = request.Headers.GetCookies(SessionIdToken).FirstOrDefault();
        if (cookie == null)
        {
            sessionId = Guid.NewGuid().ToString();
        }
        else 
        {
            sessionId = cookie[SessionIdToken].Value;
            try
            {
                Guid guid = Guid.Parse(sessionId);
            }
            catch (FormatException)
            {
                // Bad session ID. Create a new one.
                sessionId = Guid.NewGuid().ToString();
            }
        }

        // Store the session ID in the request property bag.
        request.Properties[SessionIdToken] = sessionId;

        // Continue processing the HTTP request.
        HttpResponseMessage response = await base.SendAsync(request, cancellationToken);

        // Set the session ID as a cookie in the response message.
        response.Headers.AddCookies(new CookieHeaderValue[] {
            new CookieHeaderValue(SessionIdToken, sessionId) 
        });

        return response;
    }
}
Run Code Online (Sandbox Code Playgroud)

中间件 msdn https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-5.0


Boy*_*smo 1

我刚刚解决了我的问题。withCredentials: true我认为只要你想将 cookie 发送回服务器,你只需要添加(使用 axios btw)。事实证明,如果您还想从服务器获取 cookie,则需要添加该属性。现在浏览器将 cookie 存储在Application > Cookies中。感谢所有帮助<3