如何在OpenIddict Asp.Net Core中设置Cookie存储刷新令牌
要实现把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
相关产品推荐
相关产品推荐

