ASP.NET 4.5 Web API 2.0,JWT 消息处理程序将状态 0 返回到 Angular 7 HTTP 拦截器
Posted
技术标签:
【中文标题】ASP.NET 4.5 Web API 2.0,JWT 消息处理程序将状态 0 返回到 Angular 7 HTTP 拦截器【英文标题】:ASP.NET 4.5 Web API 2.0, JWT Message Handler Returns Status 0 to Angular 7 HTTP Interceptors 【发布时间】:2019-10-08 03:21:46 【问题描述】:提前致谢。 实际上,我想使用 HTTP 拦截器在 Angular 7 应用程序中实现 JWT 刷新令牌。我已经使用 HTTP 消息处理程序 (DelegatingHandler) 实现了 JWT。在未经授权的请求中,我收到 HttpErrorResponse Status = 0 而不是 401 来刷新令牌。
浏览器窗口: 2:50191/api/test/testget:1 GET http://localhost:50191/api/test/testget401(未授权) :4200/#/login:1 从源“http://localhost:4200”访问 XMLHttpRequest 在“http://localhost:50191/api/test/testget”已被 CORS 策略阻止:请求的资源上不存在“Access-Control-Allow-Origin”标头。
.NET 4.5 Web API 2.0: 已添加 CORS。
角度: HTTP 拦截器 拦截(请求:HttpRequest,下一个:HttpHandler): 可观察的>
return next.handle(this.attachTokenToRequest(req)).pipe(
tap((event: HttpEvent<any>) =>
if (event instanceof HttpResponse)
console.log("Success");
), catchError((err): Observable<any> =>
if (err instanceof HttpErrorResponse)
switch ((<HttpErrorResponse>err).status)
case 401:
console.log("Token Expire,,, attempting
refresh");
return this.handleHttpResponseError(req, next);
case 400:
return <any>this.authService.logout();
else
return throwError(this.handleError);
)
)
API:
WebApiConfig:
public static void Register(HttpConfiguration config)
// Web API configuration and services
var cors = new EnableCorsAttribute("*", "*", "*", "*");
config.EnableCors(cors);
// Web API routes
config.MapHttpAttributeRoutes();
config.MessageHandlers.Add(new TokenValidationHandler());
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/controller/action/id",
defaults: new id = RouteParameter.Optional
);
TokenValidationHandler:
protected override async Task<HttpResponseMessage>
SendAsync(HttpRequestMessage request, CancellationToken
cancellationToken)
HttpStatusCode statusCode;
string token;
//determine whether a jwt exists or not
if (!TryRetrieveToken(request, out token))
statusCode = HttpStatusCode.Unauthorized;
//allow requests with no token - whether a action method
needs an authentication can be set with the claimsauthorization attribute
var response = await base.SendAsync(request,
cancellationToken);
//response.Headers.Add("Access-Control-Allow-Origin", "*");
return response;
try
const string sec = "5a65ed1";
var now = DateTime.UtcNow;
var securityKey = new
SymmetricSecurityKey(System.Text.Encoding.Default.GetBytes(sec));
SecurityToken securityToken;
JwtSecurityTokenHandler handler = new
JwtSecurityTokenHandler();
TokenValidationParameters validationParameters = new
TokenValidationParameters()
ValidAudience = "http://localhost:50191",
ValidIssuer = "http://localhost:50191",
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
LifetimeValidator = this.LifetimeValidator,
IssuerSigningKey = securityKey
;
//extract and assign the user of the jwt
Thread.CurrentPrincipal = handler.ValidateToken(token,
validationParameters, out securityToken);
HttpContext.Current.User = handler.ValidateToken(token,
validationParameters, out securityToken);
return await base.SendAsync(request, cancellationToken);
catch (SecurityTokenValidationException e)
statusCode = HttpStatusCode.Unauthorized;
catch (Exception)
statusCode = HttpStatusCode.InternalServerError;
return await Task<HttpResponseMessage>.Factory.StartNew(() => new
HttpResponseMessage(statusCode) );
我期待 http 状态代码 401 来刷新 jwt 令牌。
【问题讨论】:
【参考方案1】:您可以使用小型帮助程序库在本地验证令牌过期,然后在过期时重新验证或获取刷新令牌。这可能是一个更清洁的解决方案。
我在我的 auth-gard 服务中成功使用了来自 angular2-jwt 的 JwtHelper。
import JwtHelper from 'angular2-jwt';
import Injectable from '@angular/core';
import CanActivate, Router from '@angular/router';
@Injectable()
export class AuthGuard implements CanActivate
constructor(private jwtHelper: JwtHelper, private router: Router)
canActivate()
var token = localStorage.getItem("jwt");
if (token && !this.jwtHelper.isTokenExpired(token))
console.log(this.jwtHelper.decodeToken(token));
return true;
this.router.navigate(["login"]);
return false;
【讨论】:
感谢您的回答。它已经在 Guard 中实现了。在返回响应并收到正确的状态代码(400、401 等)之前,我已经解决了在“TokenValidationHandler”中附加标头(:Access-Control-Allow-Origin”:“localhost:4200")的问题。现在它正在工作。以上是关于ASP.NET 4.5 Web API 2.0,JWT 消息处理程序将状态 0 返回到 Angular 7 HTTP 拦截器的主要内容,如果未能解决你的问题,请参考以下文章
从头编写 asp.net core 2.0 web api 基础框架
应用程序中断访问 dbcontext、Asp .net 核心 web api 2.0 与实体框架核心 2.0 数据库第一种方法