如何在Startup.cs中获取当前域名

4

我有一个域名,下面有多个网站。

在我的Startup.cs中,我有以下代码:

public void ConfigureServices(IServiceCollection services)
{
    services.AddIdentity<ApplicationUser, ApplicationRole>(options =>
    {
        options.Cookies.ApplicationCookie.CookieName = "MyAppName";
        options.Cookies.ApplicationCookie.ExpireTimeSpanTimeSpan.FromMinutes(300);
     })
     .AddEntityFrameworkStores<MyDbContext, Guid>()
     .AddDefaultTokenProviders();

在生产环境下,我所有的站点都在同一网站的子文件夹中。如果使用默认域作为cookie名称,则不同站点的cookie将具有相同的名称。因此,我不想使用默认域作为cookie名称。
我希望的是获取当前域名(例如mydomain.com),然后将其附加到我在Startup.cs中为每个站点指定的显式cookie名称中。
 var domain = "get the server domain here somehow e.g. domain.com";
 ...
 options.Cookies.ApplicationCookie.CookieName = "MyAppName." + domain;

我该怎么做呢?

为什么我要问这个问题:

在Chrome开发者工具中,我可以看到cookie属于我正在访问的站点的不同域名。然而,有时我在两个不同的服务器上登录同一个站点时,会出现无法登录一个服务器且不会显示任何错误的情况。唯一的解决方法是使用另一个浏览器,因此我只能假设这种症状与cookie有关。

所以我的问题实际上是一个个人偏好的问题,因为在我的环境中,我更喜欢将域名附加到cookie名称,尽管cookie只能属于特定的域名。


如果它们有不同的域名,那么Cookie已经被分隔开了。我实际上并不明白具体的问题是什么。 - Sami Kuhmonen
是的,如果我在Chrome开发工具中查看,可以看到每个域名下的cookie是分开的。就让我们这样说吧,我想这样做并没有特定的原因,只是为了我的个人喜好,让cookie的名称包含域名。 - dfmetro
2个回答

2

首先,我会将域名存储在配置文件中。这样可以让我在当前环境下更改它。

options.Cookies.ApplicationCookie.CookieName = Configuration["DomainName"];

如果你不喜欢这种方式,你可以在登录事件上覆盖cookie选项,像这样(我不确定下面的方法是否好用):

Events = new CookieAuthenticationEvents()
{
   OnSigningIn = async (context) =>
   {
       context.Options.CookieName = "MyAppName." + context.HttpContext.Request.Host.Value.ToString();
   }
}

或者在配置中捕获第一个请求并覆盖选项

        bool firstRequest = true;
        app.Use(async (context, next) =>
        {
            if(firstRequest)
            {
                options.CookieName = "MyAppName." + context.HttpContext.Request.Host.Value.ToString();
                firstRequest = false;
            }
            await next();
        });

还可以查看类似的问题如何在不访问请求的情况下获取基本URL


我最近开始使用 Docker。虽然我的 Web 服务器监听的是 localhost:5000,但实际上它托管在 <domain.com>:80 上,因此检查 Startup.cs 中的托管参数几乎没有用处。所以对于我来说,配置设置是最好、最简单和最灵活的方式。 - Rob van der Veer
@Rob van der Veer,你说的在你的情况下可能是最好的选择,但并不适用于所有人,因为有一些应用程序服务于多个领域。 - Serg

0

我找到了另一种方法。此外,我有一个记录的博客

public class Startup
    {
        public IConfiguration Configuration { get; }
        private WebDomainHelper DomainHelper;

        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddHttpContextAccessor();
            services.AddScoped(sp => new HttpClient() { BaseAddress = new Uri(DomainHelper.GetDomain()) });
            services.AddMvc();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            DomainHelper = new WebDomainHelper(app.ApplicationServices.GetRequiredService());

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseRouting();
            app.UseEndpoints(
                endpoints =>
                {
                    endpoints.MapControllerRoute("default", "{controller=Account}/{action=Index}/{id?}");
                }
            );
        }
    }



    public class WebDomainHelper
    {
        IHttpContextAccessor ContextAccessor;
        public WebDomainHelper(IHttpContextAccessor contextAccessor)
        {
            ContextAccessor = contextAccessor;
        }

        /// 

        /// Get domain name
        /// 

        public string GetDomain()
        {
            string serverURL;
            try
            {
                serverURL = $"{ContextAccessor.HttpContext.Request.Scheme}://{ContextAccessor.HttpContext.Request.Host.Value}/";
            }
            catch
            {
                serverURL = string.Empty;
            }
            return serverURL;
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接