预先感谢。实际上,我想使用HTTP Interceptor在Angular 7应用程序中实现JWT刷新令牌。我已经使用HTTP Message Handler(DegegatingHandler(实现了JWT。在未经授权的请求下,我收到的httperrorresponse status = 0而不是401刷新令牌。
浏览器窗口: 2:50191/api/test/testget:1获取http://localhost:50191/api/test/testget 401(未经授权(:4200/#/登录:1访问XMLHTTPREQUEST,http://localhost:50191/api/test/test/testget'roench'http://localhost:4200'已被CORS策略阻止:no'访问权利:-Allow-Origin'Header在请求的资源上存在。
.NET 4.5 Web API 2.0:添加了Cors。
Angular: HTTP拦截器 拦截(req: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令牌。
您可以使用小型辅助库在本地验证令牌到期,然后在过期的情况下重新认证或获得刷新令牌。这可能是一个更干净的解决方案。
我已经在我的身材服务中使用了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;
}
}