简单的帐户注销控制器
[Authorize]
[HttpPost("logout")]
public async Task<IActionResult> Logout([FromBody]AuthTokenDTO dto)
我已经实现了一个拦截器来设置请求标头。拦截器在我的实现中很复杂。但这不是重点。
后端的注销方法不适用于我的 [Authorize] 属性,并且标头没有紧贴界面(我是这么认为的)。如果我删除控制器上的属性,那么它会进入并且模型通常会到达进行删除。
我再重复一遍,我确定没有标题,甚至在 Network 选项卡中也没有。我的拦截器很棘手,我决定让它尽可能简单,这样 100% 的标题就会紧贴。这是一个简单的拦截器,它也将标头连接到注销。Networke 在请求时已经拥有它。
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const jwt = this.tokenService.readJwtToken();
if(jwt != null){
request = request.clone({
setHeaders: {
Authorization: `Bearer ` + jwt.AccessToken
}
});
}
return next.handle(request);
}
在这里,即使使用正确的标题,它也无法正常工作。这个标头方法在 .Core 上一直对我有用。会不会有别的问题??如果我删除了授权属性,那么它会再次起作用。为什么设置了正确的标题???
启动
public class Startup
{
private readonly ILogger<Startup> Logger;
public Startup(IConfiguration configuration, ILogger<Startup> logger)
{
Configuration = configuration;
Logger = logger;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.InitializeServices();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
// In production, the Angular files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "***********";
});
services.AddDbContext<ApplicationDBContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentityCore<User>(opts =>
{
opts.Password.RequiredLength = 5; // минимальная длина
opts.Password.RequireNonAlphanumeric = false; // требуются ли не алфавитно-цифровые символы
opts.Password.RequireLowercase = true; // требуются ли символы в нижнем регистре
opts.Password.RequireUppercase = true; // требуются ли символы в верхнем регистре
opts.Password.RequireDigit = true; // требуются ли цифры
}).AddRoles<IdentityRole>()
.AddEntityFrameworkStores<ApplicationDBContext>()
.AddDefaultTokenProviders();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info { Title = "********* API", Version = "v1" });
c.AddSecurityDefinition("Bearer", new ApiKeyScheme { In = "header", Description = "Please enter JWT with Bearer into field", Name = "Authorization", Type = "apiKey" });
c.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>> {
{ "Bearer", Enumerable.Empty<string>() },
});
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsEnvironment("Testing"))
{
Logger.LogInformation("In test environment");
}
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
Logger.LogInformation("In development environment");
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseAuthentication();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseSwagger();
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
// specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "********** API V1");
c.RoutePrefix = "swagger";
});
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller}/{action=Index}/{id?}");
});
app.UseSpa(spa =>
{
// To learn more about options for serving an Angular SPA from ASP.NET Core,
// see https://go.microsoft.com/fwlink/?linkid=864501
spa.Options.SourcePath = "***********";
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
});
}
}
您已启用 asp.net 核心身份授权机制。同时,可以为身份验证 cookie 和使用 jwt 令牌的身份验证配置此机制。
在您的应用程序中,仅启用了默认机制 - 通过 cookie。因此,您的所有请求始终未经授权。
原则上,如果您仅通过 Angular 应用程序工作,那么您不需要通过 cookie 进行授权 - 只需禁用它并启用令牌授权即可。
这里还描述了一个更复杂的示例- 当还有一个 asp.net 核心应用程序使用 api 控制器的身份和 jwt 机制并且每种机制单独使用时(使用 cookie 无法访问 api 并且令牌不提供访问权限到 asp.net 核心应用程序控制器)。