c# - ASP.NET Core 中 UseHttpsRedirection 和 AddDirectToHttpsPermanent 的区别
问题描述
在Startup.cs
文件中,考虑以下内容:
public void ConfigureServices(IServiceCollection services)
{
// Irrelevant code removed
services.AddHttpsRedirection(options =>
{
options.RedirectStatusCode = StatusCodes.Status301MovedPermanently;
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// Irrelevant code removed
app.UseHttpsRedirection();
app.UseRewriter(new RewriteOptions()
.AddRedirectToWwwPermanent()
.AddRedirectToHttpsPermanent()
);
}
据我所知,我必须使用重写器来设置AddRedirectToWwwPermanent
. 我的问题是,我应该同时使用app.UseHttpsRedirection()
andAddRedirectToHttpsPermanent()
吗?或者如果他们做同样的事情,我应该删除哪个?
我只想确保与 Wwww 重定向一起正确重定向到 Https。
解决方案
AddRedirectToHttpsPermanent
(或其兄弟AddRedirectToHttps
)将 a 添加RedirectToHttpsRule
到重写器。这条规则是这样工作的:
if (!context.HttpContext.Request.IsHttps)
{
var host = context.HttpContext.Request.Host;
if (SSLPort.HasValue && SSLPort.Value > 0)
{
// a specific SSL port is specified
host = new HostString(host.Host, SSLPort.Value);
}
else
{
// clear the port
host = new HostString(host.Host);
}
var req = context.HttpContext.Request;
var newUrl = new StringBuilder().Append("https://").Append(host).Append(req.PathBase).Append(req.Path).Append(req.QueryString);
var response = context.HttpContext.Response;
response.StatusCode = StatusCode;
response.Headers[HeaderNames.Location] = newUrl.ToString();
context.Result = RuleResult.EndResponse;
context.Logger?.RedirectedToHttps();
}
所以这基本上获取了当前的主机名,并构建了一个看起来相同的新 URL,除了https://
前面有一个。然后它会设置一个 301 HTTP 状态码并通过Location
标头返回新的 URL。
然后该规则作为其中的一部分执行,RewriteMiddleware
基本上只是循环所有已注册的规则,并最终运行上述代码,然后结束响应。
相反,这是内部的工作方式:HttpsRedirectionMiddleware
if (context.Request.IsHttps || !TryGetHttpsPort(out var port))
{
return _next(context);
}
var host = context.Request.Host;
if (port != 443)
{
host = new HostString(host.Host, port);
}
else
{
host = new HostString(host.Host);
}
var request = context.Request;
var redirectUrl = UriHelper.BuildAbsolute(
"https",
host,
request.PathBase,
request.Path,
request.QueryString);
context.Response.StatusCode = _statusCode;
context.Response.Headers[HeaderNames.Location] = redirectUrl;
_logger.RedirectingToHttps(redirectUrl);
return Task.CompletedTask;
所以这将从传入的请求中获取主机名,然后使用UriHelper
看起来与当前请求完全相同的绝对 URL,只是它使用了该https://
方案。然后它设置一个 307 HTTP 状态码结果并通过Location
标头返回新的 URL。由于它不调用后面的中间件,这也将结束响应。
所以是的,这两种解决方案非常不同(不是):它们使用几乎相同的代码并产生相同的结果。唯一的实际区别是默认情况下HttpsRedirectionMiddleware
使用HTTP 307 状态代码。
如果您更喜欢一个状态码而不是另一个,您可以完全配置两个中间件以使用您的首选状态码。
那么应该使用哪个中间件来启用 HTTPS 重定向呢?这并不重要。ASP.NET Core 模板默认带有HttpsRedirectionMiddleware
,但该中间件也只存在于 ASP.NET Core 2.1 之后。
我个人会坚持使用,HttpsRedirectionMiddleware
因为它非常清楚地传达了它的目的。但是如果你有一个RewriteMiddleware
适当的位置,我会HttpsRedirectionMiddleware
用 a替换RedirectToHttpsRule
重写中间件,所以你只有一个执行重定向的中间件。——但最后,真的无所谓。
推荐阅读
- git - Github“嵌套”存储库,但不是子模块
- android - 如何制作这个 OTPView ?我想通过布局按钮而不是 Xamain.Android 中的软键盘提供输入
- postgresql - PostgreSQL 拒绝连接
- javascript - Google 应用程序脚本 - 内置依赖项验证
- powershell - $obj.psObject.properties[$key].value 可以缩写吗
- ruby-on-rails - NameError:未初始化的常量应该
- javascript - 获取最高属性的ID
- asp.net-mvc - 如何在 MVC 中从数据库中填充 DropDownList
- c - 我想将变量类型放在字符串中的某个位置
- ruby-on-rails - rails关于在不同位置显示文本和图片的操作文本