这篇文章上次修改于 840 天前,可能其部分内容已经发生变化,如有疑问可询问作者。

假设有一个博客服务,域名为 blog.abc.com,另有一个鉴权服务,域名为 login.abc.com,如何共享这两个域名的 Cookie,实现登陆功能呢?

总体来说,需要做如下两步操作:

  1. 服务端如何允许接收跨域名的请求(CORS),此处的服务端指鉴权服务端
  2. 客户端跨域名发送 Ajax 请求如何同时发送认证信息(比如 Cookie 信息),此处的客户端指浏览器端,既包括 blog.abc.com,也包括 login.abc.com

服务端如何允许接收跨域名的请求

  1. 打开 Startup.cs 文件,在 ConfigureServices 方法中添加如下代码:
    services.AddCors(options => options.AddPolicy("AllowCors", builder => builder.WithOrigins(new []{"blog.abc.com"}).AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod().AllowCredentials()));
  2. 在需要共享 CookieController 中:

    • Controller 类添加特性 [EnableCors("AllowCors")]
    • 登陆成功后返回给浏览器端的 Cookie 信息大致如下:
    var cookieOptions = new CookieOptions
    {
        HttpOnly = true,
        Secure = false,
        Domain = "abc.com",
        Path = "/",
        Expires = DateTime.Now.AddDays(7)
    };
    Response.Cookies.Append("uid", user.Uid, cookieOptions);
    Response.Cookies.Append("token", user.Token, cookieOptions);
    Response.Cookies.Append("uname", user.Uname, cookieOptions);

客户端跨域名发送 Ajax 请求如何同时发送认证信息

这个比较简单,主要是在退出登陆时需要将认证信息(Cookie)一并发送给鉴权服务,只需在 Ajax 请求中增加设置 xhrFields 即可:

$.ajax({
    type: 'DELETE',
    url: 'login.abc.com',
    xhrFields: { withCredentials: true }, // 发送凭据
    dataType: "json",
    success: function (response) {
    },
    error: function (error) {
    }
});