You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在OpenIddict Asp.Net Core中设置Cookie存储刷新令牌

在OpenIddict中用Http-only Cookie存储Refresh Token并完成认证

要实现把refresh_token存入Http-only Cookie、并通过Cookie完成刷新认证的需求,可以通过OpenIddict的事件拦截机制修改默认行为,分以下几个步骤操作:

1. 拦截Token响应,将refresh_token存入Cookie

默认OpenIddict会把refresh_token返回在响应体中,我们可以通过TokenResponseProcessed事件拦截响应,把refresh_token提取出来设置为Http-only Cookie,同时从响应体中移除该字段:

services.AddOpenIddict()
    .AddServer(options =>
    {
        // 保留你已有的OpenIddict服务配置(比如授权端点、令牌端点、加密密钥等)
        options.SetAuthorizationEndpointUris("/connect/authorize")
               .SetTokenEndpointUris("/connect/token")
               .AllowRefreshTokenFlow()
               // 其他配置...

        // 拦截Token响应,处理refresh_token的存储
        options.AddEventHandler<OpenIddictServerEvents.TokenResponseProcessed>(builder =>
        {
            builder.UseInlineHandler(context =>
            {
                if (!string.IsNullOrEmpty(context.Response.RefreshToken))
                {
                    // 配置Cookie属性:Http-only防止前端脚本读取,Secure仅在HTTPS下传输,SameSite避免CSRF
                    var cookieOptions = new CookieOptions
                    {
                        HttpOnly = true,
                        Secure = context.HttpContext.Request.IsHttps,
                        SameSite = SameSiteMode.Strict,
                        Expires = DateTimeOffset.UtcNow.AddDays(7) // 有效期需与refresh_token的过期时间一致
                    };

                    // 将refresh_token写入Cookie
                    context.HttpContext.Response.Cookies.Append("refresh_token", context.Response.RefreshToken, cookieOptions);

                    // 从响应体中移除refresh_token,避免泄露到前端
                    context.Response.RefreshToken = null;
                }

                return default;
            });
        });
    });

2. 拦截Token请求,从Cookie中读取refresh_token

当客户端需要刷新令牌时,默认OpenIddict只会从请求体(form-data)中读取refresh_token参数,我们需要通过TokenRequestReceived事件,让它支持从Cookie中获取refresh_token:

options.AddEventHandler<OpenIddictServerEvents.TokenRequestReceived>(builder =>
{
    builder.UseInlineHandler(context =>
    {
        // 仅处理refresh_token类型的请求
        if (context.Request.IsRefreshTokenGrantType() && string.IsNullOrEmpty(context.Request.RefreshToken))
        {
            // 从Cookie中读取refresh_token并赋值到请求对象
            context.Request.RefreshToken = context.HttpContext.Request.Cookies["refresh_token"];
        }

        return default;
    });
});

3. 失效时清理Cookie

当refresh_token过期或无效时,需要同步清理Cookie,避免无效的Cookie残留:

options.AddEventHandler<OpenIddictServerEvents.TokenRequestRejected>(builder =>
{
    builder.UseInlineHandler(context =>
    {
        // 仅处理refresh_token类型的请求
        if (context.Request.IsRefreshTokenGrantType())
        {
            // 删除refresh_token Cookie
            context.HttpContext.Response.Cookies.Delete("refresh_token");
        }

        return default;
    });
});

注意事项

  • Cookie的Secure属性在生产环境必须设为true,确保仅通过HTTPS传输,避免token被窃听。
  • Expires属性要和你配置的refresh_token有效期保持一致,避免Cookie未过期但token已失效的情况。
  • SameSite属性建议设为Strict或Lax,减少CSRF攻击风险。

内容的提问来源于stack exchange,提问作者Bsweest

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 23:29:55