I had this problem where reloading a page on production (Azure Linux App Service) were throwing a 404.
I managed to fix this using hashLocationStrategy in my app.routing.module.ts. But it is not SEO safe. I understand that it works because the API ignores what's after the hash, but I was wondering how could I rollback this change on the routing strategy, and handle the redirection in my API.
I looked up for something on the Internet, but I didn't manage to find anything working. I tried using app.MapWhen() or modifying app.MapControllers() to app.UseEndpoints(options => options.MapControllers()). And the more I look up for this, the more I find it very confusing.
Here is my current Program.cs :
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpsRedirection(options => options.HttpsPort = 443);
// Add services to the container.
builder.Services.AddCors(options =>
options.AddPolicy("Default", policyBuilder =>
{
policyBuilder
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
})
);
builder.Services.AddControllers();
builder.Services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(o =>
{
o.SaveToken = true;
o.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false,
ValidateAudience = false,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(
builder.Configuration
.GetSection(ApplicationSettings.Section)
.GetValue<string>("JWT:Secret")))
};
});
builder.Services.AddSwaggerGen(config =>
{
config.SwaggerDoc("Backend", new OpenApiInfo { Title = "Backend", Version = "0.1"});
config.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
In = ParameterLocation.Header,
Description = "Please enter a valid token",
Name = "Authorization",
Type = SecuritySchemeType.Http,
BearerFormat = "JWT",
Scheme = "Bearer"
});
var securityRequirement = new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
Array.Empty<string>()
}
};
config.AddSecurityRequirement(securityRequirement);
});
builder.Services.Configure<ApplicationSettings>(
builder.Configuration.GetSection(ApplicationSettings.Section));
builder.Services.AddDbContext<InstituteDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("Database")));
// Repositories
builder.Services.AddScoped<ICareCategoryRepository, CareCategoryRepository>();
builder.Services.AddScoped<ICareRepository, CareRepository>();
builder.Services.AddScoped<IUserRepository, UserRepository>();
builder.Services.AddScoped<IReservationInfoRepository, ReservationInfoRepository>();
// Services
builder.Services.AddScoped<ICareService, CareService>();
builder.Services.AddScoped<ICareCategoryService, CareCategoryService>();
builder.Services.AddScoped<IUserService, UserService>();
builder.Services.AddScoped<IReservationService, ReservationService>();
builder.Services.AddScoped<IReservationInfoService, ReservationInfoService>();
var app = builder.Build();
using (var scope = app.Services.CreateScope())
{
var services = scope.ServiceProvider;
var context = services.GetRequiredService<InstituteDbContext>();
context.Database.Migrate();
}
app.UseMiddleware<ExceptionHandlerMiddleware>();
app.UseMiddleware<JwtMiddleware>();
app.UseMiddleware<AntiXssMiddleware>();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI(options =>
{
options.SwaggerEndpoint("/swagger/Backend/swagger.json", "Backend");
});
}
else
{
app.UseHttpsRedirection();
}
app.UseRouting();
app.UseCors("Default");
app.UseAuthentication();
app.UseAuthorization();
app.UseDefaultFiles();
app.UseStaticFiles();
app.MapControllers();
app.Run();
EDIT : Here is the .htaccess file I used (there is more than just url rewriting)
RewriteEngine On
# Redirection to HTTPS:
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# Redirection of requests to index.html
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^.*$ - [NC,L]
# Redirect all non-file routes to index.html
RewriteRule ^(?!.*\.).*$ index.html [NC,L]