简体   繁体   English

带有ASP.NET Core 2.0的Angular 4在JWT(CORS)上返回了401错误

[英]Angular 4 with ASP.NET Core 2.0 is giving back 401 error on JWT (CORS)

I´ve written front-end application in Angular 4. This front-end is trying to make a request to endpoints which required authorization token. 我已经用Angular 4编写了前端应用程序。该前端试图向要求授权令牌的端点发出请求。 I am using JWT token with ASP.NET Core 2.0. 我在ASP.NET Core 2.0中使用JWT令牌。 Because both are running on different ports, i have to set CORS . 因为两者都在不同的端口上运行,所以我必须设置CORS

So request with added Authorization header returns response from server with 401 Error code. 因此,添加了Authorization标头的请求会从服务器返回带有401 Error code.响应401 Error code. I tried to use many solution from these threads: 我尝试从这些线程使用许多解决方案:

  1. Setting cors there is also idea with custom CorsMiddleware, 使用自定义的CorsMiddleware也可以 设置 cors,
    which I Tried, but still receiving 401. 我尝试过,但仍然收到401。
  2. Similiar solution to custom Cors middleware 定制Cors中间件的类似解决方案
  3. Custom cors middleware This wasn´t even working 自定义cors中间件 这甚至 行不通


, which at first glance appear to be solving a similar problem. 乍一看似乎正在解决类似的问题。 However, I am not able to get right response from server. 但是,我无法从服务器获得正确的响应。 Method without attribute [Authorize] are working correctly ( Methods which don´t need Bearer token ) Could be error somewhere else? 没有属性[Authorize]方法可以正常工作( 不需要Bearer令牌的方法 )在其他地方可能会出错吗? (Token are indeed valid, tested from POSTMAN). (令牌确实有效,已通过POSTMAN测试)。 Have anybody idea, what's could be a problem? 有任何想法,可能是什么问题?


This is how I set CORS 这就是我设置CORS的方式

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(options =>
    {
        options.AddPolicy("CorsPolicy",
            builder => builder.WithOrigins("http://localhost:4200")
                .AllowAnyMethod()
                .AllowAnyHeader());
    });
}

Apply Cors before Mvc 在Mvc之前应用Cors

public void Configure(IApplicationBuilder app,
IHostingEnvironment env, UnitOfWork identityCustomDbContext)
{

    app.UseCors("CorsPolicy");
    app.UseMvc();

}


Angular token interceptor 角度令牌拦截器

export class TokenInterceptor implements HttpInterceptor {
    constructor(private injector: Injector, private _router: Router){}

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>{
        const auth = this.injector.get(AuthService);
        let token = auth.getToken();
        if(token){
                const authReq = req.clone({headers:req.headers.set('Authorization', token).set('Content-Type','application/json')})
                return next.handle(authReq);
        }
    }
}

Requests headers 请求标头


OPTIONS request 选项要求
status code: 204 No Content 状态码:204无内容

 OPTIONS http://localhost:57498/api/users Host: localhost:57498 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Access-Control-Request-Method: GET Access-Control-Request-Headers: authorization,content-type Origin: http://localhost:4200 Connection: keep-alive 

OPTIONS response 选项回应

 Server: Kestrel Access-Control-Allow-Headers: authorization,content-type Access-Control-Allow-Origin: http://localhost:4200 X-SourceFiles: =?UTF-8?B?RDpcQ29uZmVlLWJhY2tlbmRcQ29uZmVlLXdlYkFwaVxDb25mZWUtd2ViQXBpXGFwaVx1c2Vycw==?= X-Powered-By: ASP.NET 

GET request GET请求
status code: 401 Unauthorized 状态码:401未经授权

 Accept: application/json, text/plain, */* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Referer: http://localhost:4200/admin/conferences Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJsdUBzLmNvbSIsImp0aSI6ImJmMDk3ZmYwLTRjMGUtNGZkMC04YTM1LTQ4MzZlY2U2OGE0OSIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWVpZGVudGlmaWVyIjoiYmMzZWQxMzQtMTAyNS00OWVjLTk1YWYtZDk0ODMxNWVmYzI0IiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy9yb2xlIjoiQWRtaW5pc3RyYXRvciIsImV4cCI6MTUyMDUzNzQ3MCwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo1NzQ5OC8iLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjU3NDk4LyJ9.rUwoq_olnVg7lOvtX1AIpB1JDDwBi9ra3FhBLaSSLuQ Content-Type: application/json Origin: http://localhost:4200 Connection: keep-alive 

GET response GET回应

 Server: Kestrel WWW-Authenticate: Bearer Access-Control-Allow-Origin: http://localhost:4200 X-SourceFiles: =?UTF-8?B?RDpcQ29uZmVlLWJhY2tlbmRcQ29uZmVlLXdlYkFwaVxDb25mZWUtd2ViQXBpXGFwaVx1c2Vycw==?= X-Powered-By: ASP.NET Content-Length: 0 


According to link 2 and 3 above, I tried to implement custom CORS middleware 根据上面的链接2和3,我尝试实现自定义的CORS中间件

 public class CorsMiddleware { private readonly RequestDelegate _next; public CorsMiddleware(RequestDelegate next) { _next = next; } public Task Invoke(HttpContext httpContext) { httpContext.Response.Headers.Add("Access-Control-Allow-Origin", "*"); httpContext.Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type, Authorization, X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Date, X-Api-Version, X-File-Name"); httpContext.Response.Headers.Add("Access-Control-Allow-Methods", "POST,GET,PUT,PATCH,DELETE,OPTIONS"); return _next(httpContext); } } public static class CorsMiddlewareExtensions { public static IApplicationBuilder UseCorsMiddleware(this IApplicationBuilder builder) { return builder.UseMiddleware<CorsMiddleware>(); } } 
 public void Configure(IApplicationBuilder app, IHostingEnvironment env, UnitOfWork identityCustomDbContext) { app.UseCorseMiddleware(); app.UseMvc(); app.UseCors("CorsPolicy"); } 

The result was same. 结果是一样的。 I have recieved 401 from server. 我已经从服务器收到401。

Posting my comment as an answer. 发表我的评论作为答案。

You are passing a token to the service, but you are not including the word bearer before the token string, so the service has no clue what to do with it, thus the 401 Unauthorized. 您正在将令牌传递给服务,但没有在令牌字符串之前包含单词不记名 ,因此该服务不知道如何处理它,因此不知道是401 Unauthorized。

Easy enough to miss. 很容易错过。 Postman handles this for you, so you may not think about it with Angular. 邮递员为您处理此问题,因此您可能不会想到Angular。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM