在Angular6中向服务器发送请求时,来自服务器的未授权错误

时间:2018-12-15 10:36:08

标签: javascript asp.net angular asp.net-core angular6

我需要创建一个带有angular6和aspcore的网站。

我用ASP核心创建服务器,并创建此令牌:

{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJhYzQ3NjJjZi0xNDdmLTJmZmYtZTQ1Yy05ZDNjNjJkYTAwMDEiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjQ0MzkwLyIsImlhdCI6MTU0NDg2OTU1OSwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvbmFtZWlkZW50aWZpZXIiOiIzMDAyIiwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvbmFtZSI6ImtpYUBraWEuY29tIiwiRGlzcGxheU5hbWUiOiLYotix2LQg2KjYsdmH2KfZhtuMIiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy9zZXJpYWxudW1iZXIiOiI0Njg0NjM0NjQiLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3VzZXJkYXRhIjoiMzAwMiIsIm5iZiI6MTU0NDg2OTU1OSwiZXhwIjoxNTQ0ODY5Njc5LCJhdWQiOiJBbnkifQ.zhW3aoRKGaoy-wEbO7RnbdQmxCXSy50pSaqO1OoEwe8",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJiMDEyNTQxYi0yZDljLTE2N2UtZDM0Ni1hZjNlNWRiYjMzYzgiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjQ0MzkwLyIsImlhdCI6MTU0NDg2OTU1OSwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy9zZXJpYWxudW1iZXIiOiIwZGMwMTRmNDc1NTQ1Y2MyYjEwNzUzZjU1YTFlOTQxNyIsIm5iZiI6MTU0NDg2OTU1OSwiZXhwIjoxNTQ0ODczMTU5LCJhdWQiOiJBbnkifQ.8vwTvDJcT8MoOfvqVb7gGzSxbll2_u91bArumJDW65k"
}

这是我寻找userInfo的服务:

  public UserInfo(username:string):Observable<IUser>{
return this.http.get<IUser>(`${this.baseUrl+'GetUserInfo/'}${username}`,{headers:{
  'Content-Type': 'application/json; charset=utf-8',
  'Authorization': 'Bearer ' + this.broserStorage.GetLocalStorage('AccessToken')+this.broserStorage.GetLocalStorage('RefreshToken'),
},
})
.pipe(
  tap((user: IUser) => this.log(`GetUserInfo user w/ email=${user}`)),
  catchError(this.handleError<IUser>('GetUserInfo user'))
);

}

我发送了请求,但显示了此错误:

  

GetUserInfo用户失败:https://localhost:44390/api/user/GetUserInfo/kia@kia.com的Http错误响应:401未经授权

什么问题?来自服务器还是Angular?

此代码来自服务器:

[HttpGet("GetUserInfo/{username}")]
    [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
    public async Task<IActionResult> GetUSerInfo(string username)
    {
        UserRoleViewModel URVM = new UserRoleViewModel();
        var user = await _applicationUserManager.FindByNameAsync(username);
        if (user != null)
        {
            var roles = await _applicationUserManager.GetRolesAsync(user);
            var roleName = await _applicationRoleManager.FindRoleByNameList(roles[0]);
            URVM.Id = user.Id;
            URVM.Email = user.Email;
            URVM.BirthDate = user.BirthDate;
            URVM.CreatedDateTime = user.CreatedDateTime;
            URVM.FirstName = user.FirstName;
            URVM.IsActive = user.IsActive;
            URVM.PhoneNmuberConfirmed = user.PhoneNumberConfirmed;
            URVM.IsEmailPublic = user.IsEmailPublic;
            URVM.LastName = user.LastName;
            URVM.TwoFactorEnabled = user.TwoFactorEnabled;
            URVM.EmailConfirmed = user.EmailConfirmed;
            URVM.LockoutEnabled = user.LockoutEnabled;
            URVM.LastVisitDateTime = user.LastVisitDateTime;
            URVM.Location = user.Location;
            URVM.PhotoFileName = user.PhotoFileName;
            URVM.RoleLevel = roleName.RoleLevel;
            URVM.Description = roleName.Description;
            URVM.roleId = roleName.Id;
            URVM.desplayName = user.FirstName + " " + user.LastName;
            return Ok(URVM);
        }
        return BadRequest();
    }

此启动:

services.AddCors(options =>
        {
            options.AddPolicy("CorsPolicy",
                builder => builder
                    .WithOrigins("http://localhost:4200") //Note:  The URL must be specified without a trailing slash (/).
                    .AllowAnyMethod()
                    .AllowAnyHeader()
                    .AllowCredentials());
        });
        services.AddIdentity<User, Role>().AddUserStore<ApplicationUserStore>()
            .AddUserManager<ApplicationUserManager>()
            .AddRoleStore<ApplicationRoleStore>()
            .AddRoleManager<ApplicationRoleManager>()
            .AddSignInManager<ApplicationSignInManager>()
            .AddDefaultTokenProviders();
        services
           .AddAuthentication(options =>
           {
               options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
               options.DefaultSignInScheme = JwtBearerDefaults.AuthenticationScheme;
               options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
           })
           .AddJwtBearer(cfg =>
           {
               cfg.RequireHttpsMetadata = false;
               cfg.SaveToken = true;
               cfg.TokenValidationParameters = new TokenValidationParameters
               {
                   ValidIssuer = Configuration["BearerTokens:Issuer"], // site that makes the token
                   ValidateIssuer = false, // TODO: change this to avoid forwarding attacks
                   ValidAudience = Configuration["BearerTokens:Audience"], // site that consumes the token
                   ValidateAudience = false, // TODO: change this to avoid forwarding attacks
                   IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["BearerTokens:Key"])),
                   ValidateIssuerSigningKey = true, // verify signature to avoid tampering
                   ValidateLifetime = true, // validate the expiration
                   ClockSkew = TimeSpan.Zero // tolerance for the expiration date
               };
               cfg.Events = new JwtBearerEvents
               {
                   OnAuthenticationFailed = context =>
                   {
                       var logger = context.HttpContext.RequestServices.GetRequiredService<ILoggerFactory>().CreateLogger(nameof(JwtBearerEvents));
                       logger.LogError("Authentication failed.", context.Exception);
                       return Task.CompletedTask;
                   },
                   OnTokenValidated = context =>
                   {
                       var tokenValidatorService = context.HttpContext.RequestServices.GetRequiredService<ITokenValidatorService>();
                       return tokenValidatorService.ValidateAsync(context);
                   },
                   OnMessageReceived = context =>
                   {
                       return Task.CompletedTask;
                   },
                   OnChallenge = context =>
                   {
                       var logger = context.HttpContext.RequestServices.GetRequiredService<ILoggerFactory>().CreateLogger(nameof(JwtBearerEvents));
                       logger.LogError("OnChallenge error", context.Error, context.ErrorDescription);
                       return Task.CompletedTask;
                   }
               };
           });
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseExceptionHandler(appBuilder =>
        {
            appBuilder.Use(async (context, next) =>
            {
                var error = context.Features[typeof(IExceptionHandlerFeature)] as IExceptionHandlerFeature;
                if (error != null && error.Error is SecurityTokenExpiredException)
                {
                    context.Response.StatusCode = 401;
                    context.Response.ContentType = "application/json";
                    await context.Response.WriteAsync(JsonConvert.SerializeObject(new
                    {
                        State = 401,
                        Msg = "token expired"
                    }));
                }
                else if (error != null && error.Error != null)
                {
                    context.Response.StatusCode = 500;
                    context.Response.ContentType = "application/json";
                    await context.Response.WriteAsync(JsonConvert.SerializeObject(new
                    {
                        State = 500,
                        Msg = error.Error.Message
                    }));
                }
                else
                {
                    await next();
                }
            });
        });
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseCors("CorsPolicy");
        app.UseAuthentication();
        var scopeFactory = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>();
        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "areas",
                template: "{area:exists}/{controller=Home}/{action=Index}/{id?}"
            );
        });
    }

修改

我添加了此类:

    @Injectable()
export class AuthInterceptorService implements HttpInterceptor  {

  private delayBetweenRetriesMs = 1000;
  private numberOfRetries = 3;
  private authorizationHeader = "Authorization";

  constructor(
    private tokenStoreService: TokenstoreService,
    private router: Router) { }

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const accessToken = this.tokenStoreService.getRawAuthToken(AuthTokenType.AccessToken);
    if (accessToken) {
      console.log('in if')
      request = request.clone({
        headers: request.headers.set(this.authorizationHeader, `Bearer ${accessToken}`)
      });
      return next.handle(request).pipe(
        retryWhen(errors => errors.pipe(
          mergeMap((error: HttpErrorResponse, retryAttempt: number) => {
            if (retryAttempt === this.numberOfRetries - 1) {
              console.log(`HTTP call '${request.method} ${request.url}' failed after ${this.numberOfRetries} retries.`);
              return throwError(error); // no retry
            }

            switch (error.status) {
              case 400:
              case 404:
                return throwError(error); // no retry
            }

            return of(error); // retry
          }),
          delay(this.delayBetweenRetriesMs),
          take(this.numberOfRetries)
        )),
        catchError((error: any, caught: Observable<HttpEvent<any>>) => {
          console.error({ error, caught });
          if (error.status === 401 || error.status === 403) {
            const newRequest = this.getNewAuthRequest(request);
            if (newRequest) {
              console.log("Try new AuthRequest ...");
              return next.handle(newRequest);
            }
            this.router.navigate(["/accessDenied"]);
          }
          return throwError(error);
        })
      );
    } else {
      // login page
      return next.handle(request);
    }
  }

  getNewAuthRequest(request: HttpRequest<any>): HttpRequest<any> | null {
    const newStoredToken = this.tokenStoreService.getRawAuthToken(AuthTokenType.AccessToken);
    const requestAccessTokenHeader = request.headers.get(this.authorizationHeader);
    if (!newStoredToken || !requestAccessTokenHeader) {
      console.log(" first =>There is no new AccessToken.", { requestAccessTokenHeader: requestAccessTokenHeader, newStoredToken: newStoredToken });
      return null;
    }
    const newAccessTokenHeader = `Bearer ${newStoredToken}`;
    if (requestAccessTokenHeader === newAccessTokenHeader) {
      console.log(" second =>There is no new AccessToken.", { requestAccessTokenHeader: requestAccessTokenHeader, newAccessTokenHeader: newAccessTokenHeader });
      return null;
    }
    console.log("third")
    return request.clone({ headers: request.headers.set(this.authorizationHeader, newAccessTokenHeader) });
}
}

并将其添加到appmodule中:

    { provide: HTTP_INTERCEPTORS,useClass: AuthInterceptorService,multi: true},

和此请求:

  public UserInfo(username:string):Observable<IUser>{
return this.http.get<IUser>(`${this.baseUrl+'GetUserInfo/'}${username}`,{headers:{
  'Content-Type': 'application/json; charset=utf-8'
},
})
.pipe(
  tap((user: IUser) => this.log(`GetUserInfo user w/ email=${user}`)),
  catchError(this.handleError<IUser>('GetUserInfo user'))
);

}

但是它告诉我这个错误:

  

second =>没有新的AccessToken。   对象{requestAccessTokenHeader: “承载\” \\ “eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI0NDZlODZiYi01ZTg2LTEyMjQtNTBmYi1jZGNjOWUwMjkzMDEiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjQ0MzkwLyIsImlhdCI6MTU0NDg5MzE4NCwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvbmFtZWlkZW50aWZpZXIiOiIzMDAyIiwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvbmFtZSI6ImtpYUBraWEuY29tIiwiRGlzcGxheU5hbWUiOiLYotix2LQg2KjYsdmH2KfZhtuMIiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy9zZXJpYWxudW1iZXIiOiI0Njg0NjM0NjQiLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3VzZXJkYXRhIjoiMzAwMiIsIm5iZiI6MTU0NDg5MzE4NCwiZXhwIjoxNTQ0ODkzMzA0LCJhdWQiOiJBbnkifQ.NNKPkwayicwLo8K-K1weP7vGAkL8Cpo9Zx-xtrh6I4E \\” \ “”,newAccessTokenHeader: “承载\” \\“eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI0NDZlODZiYi01ZTg2LTEyMjQtNTBmYi1jZGNjOWUwMjkzMDEiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjQ0MzkwLyIsImlhdCI6MTU0NDg5MzE4NCwiaHR0cDovL3Nja GVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvbmFtZWlkZW50aWZpZXIiOiIzMDAyIiwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvbmFtZSI6ImtpYUBraWEuY29tIiwiRGlzcGxheU5hbWUiOiLYotix2LQg2KjYsdmH2KfZhtuMIiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy9zZXJpYWxudW1iZXIiOiI0Njg0NjM0NjQiLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3VzZXJkYXRhIjoiMzAwMiIsIm5iZiI6MTU0NDg5MzE4NCwiZXhwIjoxNTQ0ODkzMzA0LCJhdWQiOiJBbnkifQ.NNKPkwayicwLo8K-K1weP7vGAkL8Cpo9Zx-xtrh6I4E \\ “\””}   auth-interceptor.service.ts:74:6   对象{标头:{…},状态:401,statusText:“未经授权”,url:“ https://localhost:44390/api/user/GetUserInfo/kia@kia.com”,确定:false,名称:“ HttpErrorResponse”,消息:“ https://localhost:44390/api/user/GetUserInfo/kia@kia.com的Http失败响应:401未经授权”,错误:null}   user.service.ts:113:6   GetUserInfo用户失败:https://localhost:44390/api/user/GetUserInfo/kia@kia.com的Http错误响应:401未经授权

0 个答案:

没有答案