I det här inlägget beskriver jag hur du kan omdirigera förfrågningar till https och www eller icke-www genom att använda en omdirigeringsregel i ASP.NET Core. Anledningarna till att göra en omdirigering (301) är förbättrad SEO och högre säkerhet avseende hemsidan.
Det är bättre att bara ha en version av din webbplats i sökmotorer, om du har flera versioner av din webbplats (http://, http:// www.https://, https://www.) kan din hemsida bli straffad i sökrankingen på grund av duplicerat innehåll.
Hyper Text Transfer Protocol Secure (HTTPS) är en säker version av Hyper Text Transfer Protocol (HTTP). Https betyder att all kommunikation mellan en webbläsare och en server är krypterad, detta gör det mycket svårt för en man i mitten att få information från data som skickas mellan en webbläsare och en server.
Varför en 301 omdirigering? En 301-omdirigering är en permanent omdirigering från en webbadress till en annan webbadress, detta betyder att sökmotorer vet att den URL du vidarebefordrar till är rätt webbadress och att alla sökrankningspoäng ska gälla för den här webbadressen.
Omdirigeringsregel
Jag har skapat en omskrivningsregel som ansvarar för omdirigeringar i applikationen. Jag har använt ett mellanprogram för omdirigeringar tidigare, men det slutade att fungera när jag uppgraderade från ASP.NET Core 2.2 till ASP.NET Core 3.1. Denna regel kommer bara att göra en omdirigering, jag tycker att det är bättre att bara göra en omdirigering jämfört med att göra flera omdirigeringar om vi använder flera regler.
using System;
using Microsoft.Net.Http.Headers;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Rewrite;
namespace Annytab.Rules
{
/// <summary>
/// This class handles redirects to https, www, non-www
/// </summary>
public class RedirectHttpsWwwNonWwwRule : IRule
{
#region Variables
public int status_code { get; set; }
public bool redirect_to_www { get; set; }
public bool redirect_to_non_www { get; set; }
public bool redirect_to_https { get; set; }
public string[] hosts_to_ignore { get; set; }
#endregion
#region Constructors
/// <summary>
/// Create a new rule
/// </summary>
public RedirectHttpsWwwNonWwwRule()
{
// Set values for instance variables
this.status_code = 301;
this.redirect_to_www = false;
this.redirect_to_non_www = false;
this.redirect_to_https = false;
this.hosts_to_ignore = new string[] { "localhost" };
} // End of the constructor
#endregion
#region methods
/// <summary>
/// Apply the rule
/// </summary>
public virtual void ApplyRule(RewriteContext context)
{
// Get the request
HttpRequest req = context.HttpContext.Request;
// Get the host
string host = req.Host.Host;
// Create an uri builder with the current request
UriBuilder uriBuilder = new UriBuilder(host + req.Path + req.QueryString);
uriBuilder.Scheme = req.Scheme;
uriBuilder.Port = req.IsHttps == true ? 443 : 80;
// Check hosts to ignore
for (int i = 0; i < hosts_to_ignore.Length; i++)
{
if (host.Equals(hosts_to_ignore[i], StringComparison.OrdinalIgnoreCase))
{
context.Result = RuleResult.ContinueRules;
return;
}
}
// Check if we should do a https redirect
if (this.redirect_to_https == true && req.IsHttps == false)
{
// Add https scheme and port
uriBuilder.Scheme = "https";
uriBuilder.Port = 443;
// Check if we should do a www redirect
if(this.redirect_to_www == true && this.redirect_to_non_www == false && host.StartsWith("www") == false)
{
uriBuilder.Host = "www." + uriBuilder.Host;
}
else if (this.redirect_to_non_www == true && this.redirect_to_www == false && host.StartsWith("www") == true)
{
uriBuilder.Host = uriBuilder.Host.Replace("www.", "");
}
// Do a redirect
HttpResponse response = context.HttpContext.Response;
response.StatusCode = this.status_code;
response.Headers[HeaderNames.Location] = uriBuilder.Uri.AbsoluteUri;
context.Result = RuleResult.EndResponse;
return;
}
else if (this.redirect_to_www == true && this.redirect_to_non_www == false && host.StartsWith("www.") == false)
{
// Modify the host
uriBuilder.Host = "www." + uriBuilder.Host;
// Do a redirect
HttpResponse response = context.HttpContext.Response;
response.StatusCode = this.status_code;
response.Headers[HeaderNames.Location] = uriBuilder.Uri.AbsoluteUri;
context.Result = RuleResult.EndResponse;
return;
}
else if (this.redirect_to_non_www == true && this.redirect_to_www == false && host.StartsWith("www.") == true)
{
// Modify the url
uriBuilder.Host = uriBuilder.Host.Replace("www.", "");
// Do a redirect
HttpResponse response = context.HttpContext.Response;
response.StatusCode = this.status_code;
response.Headers[HeaderNames.Location] = uriBuilder.Uri.AbsoluteUri;
context.Result = RuleResult.EndResponse;
return;
}
else
{
context.Result = RuleResult.ContinueRules;
return;
}
} // End of the ApplyRule method
#endregion
} // End of the class
} // End of the namespace
Använd omskrivningsregeln
Vår omdirigeringsregel läggs till i metoden Configure i klassen StartUp och denna regel används för att omdirigera till https och till www eller icke-www. Jag använder IWebsiteSettingRepository
website_settings_repository för att lagra information om jag skall göra en www-omdirigering, en icke-www-omdirigering och om jag skall göra en https-omdirigering. KeyStringList är en hanteringsklass för en uppslagsbok (Dictionary) med strängar, den här klassen gör det lättare att hämta värden från uppslagsboken.
// Add redirection and use a rewriter
RedirectHttpsWwwNonWwwRule rule = new RedirectHttpsWwwNonWwwRule
{
status_code = 301,
redirect_to_https = redirect_https,
redirect_to_www = redirect_www,
redirect_to_non_www = redirect_non_www,
hosts_to_ignore = new string[] {"localhost", "fotbollstabeller001.azurewebsites.net" }
};
RewriteOptions options = new RewriteOptions();
options.Rules.Add(rule);
app.UseRewriter(options);
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IWebsiteSettingRepository website_settings_repository)
{
// Use error handling
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseStatusCodePagesWithReExecute("/home/error/{0}");
}
// Get website settings
KeyStringList settings = website_settings_repository.GetAllFromCache();
bool redirect_https = settings.Get("REDIRECT-HTTPS") == "true" ? true : false;
bool redirect_www = settings.Get("REDIRECT-WWW") == "true" ? true : false;
bool redirect_non_www = settings.Get("REDIRECT-NON-WWW") == "true" ? true : false;
// Add redirection and use a rewriter
RedirectHttpsWwwNonWwwRule rule = new RedirectHttpsWwwNonWwwRule
{
status_code = 301,
redirect_to_https = redirect_https,
redirect_to_www = redirect_www,
redirect_to_non_www = redirect_non_www,
hosts_to_ignore = new string[] {"localhost", "fotbollstabeller001.azurewebsites.net" }
};
RewriteOptions options = new RewriteOptions();
options.Rules.Add(rule);
app.UseRewriter(options);
// Use static files
app.UseStaticFiles(new StaticFileOptions
{
OnPrepareResponse = ctx =>
{
// Cache static files for 30 days
ctx.Context.Response.Headers.Append("Cache-Control", "public,max-age=25920000");
ctx.Context.Response.Headers.Append("Expires", DateTime.UtcNow.AddDays(300).ToString("R", CultureInfo.InvariantCulture));
}
});
// Use sessions
app.UseSession();
// For most apps, calls to UseAuthentication, UseAuthorization, and UseCors must
// appear between the calls to UseRouting and UseEndpoints to be effective.
app.UseRouting();
// Use authentication and authorization middlewares
app.UseAuthentication();
app.UseAuthorization();
// Routing endpoints
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
"default",
"{controller=home}/{action=index}/{id?}");
});
} // End of the Configure method