Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/31.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 401错误代码上未刷新刷新令牌_Angular_Asp.net Core - Fatal编程技术网

Angular 401错误代码上未刷新刷新令牌

Angular 401错误代码上未刷新刷新令牌,angular,asp.net-core,Angular,Asp.net Core,每个教程和代码段都在使用这种刷新令牌代码:在我的例子中,这根本不起作用,因为this.authService.refreshttoken()执行HTTP post请求,直到发出订阅()后才会执行调用。当我添加subscribe调用时,它会在一个新请求中调用httppost,但这在我的脑海中是一团糟的。你能解释一下并告诉我如何正确处理这个问题吗?请不要将我已经看到的片段链接到我 有关我的ASP.NET Core 2.2 Web API后端的信息: /api/auth/login返回AccessT

每个教程和代码段都在使用这种刷新令牌代码:在我的例子中,这根本不起作用,因为
this.authService.refreshttoken()
执行HTTP post请求,直到发出
订阅()
后才会执行调用。当我添加subscribe调用时,它会在一个新请求中调用httppost,但这在我的脑海中是一团糟的。你能解释一下并告诉我如何正确处理这个问题吗?请不要将我已经看到的片段链接到我

有关我的ASP.NET Core 2.2 Web API后端的信息:

  • /api/auth/login返回AccessToken(JWT令牌+刷新令牌字符串)。JWT令牌将在1分钟内过期,仅用于测试目的。刷新令牌将在10分钟后过期
  • /api/auth/token/refresh返回一个新的AccessTokenJWT和Refresh令牌都将重新创建。另一件重要的事情是如果Refresh令牌过期,并且在此之后发出了刷新请求,则返回一个BADDREQUEST,该请求应该在角度部分进行处理,可能在管道内部有一个
    catchError()
  • /api/auth/logout将撤销刷新令牌。因此,基本上,在
    this.authService.logout()
    上也会有http post请求,即使它不在我下面给出的代码中
auth.interceptor.ts

import { Injectable } from '@angular/core';
import {
  HttpEvent,
  HttpInterceptor,
  HttpHandler,
  HttpRequest,
  HttpErrorResponse
} from '@angular/common/http';
import { Observable, throwError, BehaviorSubject } from 'rxjs';
import { catchError, switchMap } from 'rxjs/operators';

import { AuthService } from '../services/auth.service';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  private refreshTokenInProgress = false;
  private tokenSubject = new BehaviorSubject<any>(null);

  constructor(private authService: AuthService) { }

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(request)
      .pipe(
        catchError((error: HttpErrorResponse) => {

          if (error instanceof HttpErrorResponse) {
            if (error.status === 401) {
              return this.handleHttpResponseError(request, next);
            }
          }

          return throwError(error);
        })
      );
  }

  private handleHttpResponseError(request: HttpRequest<any>, next: HttpHandler) {
    const accessToken = this.authService.getJwtToken();

    // if jwt token is not set, we just let the request execute
    if (!accessToken) {
      return next.handle(request);
    }

    // if jwt token has not expired yet, we add the authorize header
    // otherwise we refresh the token
    if (!this.authService.isTokenExpired()) {
      console.log('added authorization to the headers')

      return next.handle(this.attachTokenToRequest(request, accessToken));
    } else {
      console.log('token expired');

      this.authService.refreshToken()
        .pipe(
          switchMap(result => {
            console.log(`API returned: ${result}`);

            return next.handle(this.attachTokenToRequest(request, accessToken));
          })
        );

      return next.handle(request);
    }
  }

  private attachTokenToRequest(request: HttpRequest<any>, token: string) {
    return request.clone({
      setHeaders: {
        Authorization: `Bearer ${token}`
      }
    });
  }
}
从'@angular/core'导入{Injectable};
进口{
HttpEvent,
HttpInterceptor,
HttpHandler,
HttpRequest,
HttpErrorResponse
}来自“@angular/common/http”;
从“rxjs”导入{observatable,throwError,BehaviorSubject};
从“rxjs/operators”导入{catchError,switchMap};
从“../services/auth.service”导入{AuthService};
@可注射()
导出类AuthInterceptor实现HttpInterceptor{
私有refreshTokenInProgress=false;
私有令牌主体=新行为主体(null);
构造函数(私有authService:authService){}
拦截(请求:HttpRequest,下一步:HttpHandler):可观察{
返回next.handle(请求)
.烟斗(
catchError((错误:HttpErrorResponse)=>{
if(HttpErrorResponse的错误实例){
如果(error.status==401){
返回此.handleHttpResponseError(请求,下一步);
}
}
返回投掷器(错误);
})
);
}
私有handleHttpResponseError(请求:HttpRequest,下一步:HttpHandler){
const accessToken=this.authService.getJwtToken();
//如果没有设置jwt令牌,我们就让请求执行
如果(!accessToken){
下一步返回。处理(请求);
}
//如果jwt令牌尚未过期,则添加authorize标头
//否则我们刷新令牌
如果(!this.authService.isTokenExpired()){
console.log('向标头添加了授权')
返回next.handle(this.attachtokentoquest(request,accessToken));
}否则{
console.log('tokenexpired');
this.authService.refreshToken()
.烟斗(
开关映射(结果=>{
log(`API返回:${result}`);
返回next.handle(this.attachtokentoquest(request,accessToken));
})
);
下一步返回。处理(请求);
}
}
私有attachTokenToRequest(请求:HttpRequest,令牌:string){
return request.clone({
集合标题:{
授权:`Bearer${token}`
}
});
}
}
auth.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { environment } from 'src/environments/environment';
import { map } from 'rxjs/operators';
import { JwtHelperService } from '@auth0/angular-jwt';

import { AccessToken } from '../types/user';

@Injectable()
export class AuthService {
  private actionUrl: string;
  private readonly JWT_TOKEN = 'access_token';
  private readonly REFRESH_TOKEN = 'refresh_token';

  constructor(private httpClient: HttpClient) {
    this.actionUrl = `${environment.baseUrls.server}api/auth`;
  }

  isLoggedIn(): boolean {
    return !!this.getJwtToken();
  }

  login(credentials: { email: string, password: string }) {
    return this.httpClient.post<AccessToken>(`${this.actionUrl}/login`, credentials)
      .pipe(
        map(tokens => {
          this.setJwtToken(tokens.accessToken);
          this.setRefreshToken(tokens.refreshToken);
          return true;
        })
      );
  }

  refreshToken() {
    console.log('refreshToken() called');

    const helper = new JwtHelperService();
    const email = helper.decodeToken(this.getJwtToken()).sub;

    return this.httpClient.post<AccessToken>(`${this.actionUrl}/token/refresh`, { 'refreshToken': localStorage.getItem(this.REFRESH_TOKEN), 'email': email })
      .pipe(
        map(tokens => {
          console.log('refreshToken().pipe called()');

          this.setJwtToken(tokens.accessToken);
          this.setRefreshToken(tokens.refreshToken);
          return true;
        })
      );
  }

  logout() {
    localStorage.removeItem(this.JWT_TOKEN);
    localStorage.removeItem(this.REFRESH_TOKEN);
  }

  isTokenExpired(): boolean {
    const helper = new JwtHelperService();
    return helper.isTokenExpired(this.getJwtToken());
  }

  getJwtToken(): string {
    return localStorage.getItem(this.JWT_TOKEN);
  }

  setJwtToken(token: string) {
    localStorage.setItem(this.JWT_TOKEN, token);
  }

  getRefreshToken(): string {
    return localStorage.getItem(this.REFRESH_TOKEN);
  }

  setRefreshToken(token: string) {
    localStorage.setItem(this.REFRESH_TOKEN, token);
  }
}
从'@angular/core'导入{Injectable};
从'@angular/common/http'导入{HttpClient};
从'src/environments/environment'导入{environment};
从“rxjs/operators”导入{map};
从'@auth0/jwt'导入{JwtHelperService};
从“../types/user”导入{AccessToken};
@可注射()
导出类身份验证服务{
私有actionUrl:string;
私有只读JWT_令牌='访问_令牌';
私有只读刷新令牌='刷新令牌';
构造函数(私有httpClient:httpClient){
this.actionUrl=`${environment.baseUrls.server}api/auth`;
}
isLoggedIn():布尔值{
return!!this.getJwtToken();
}
登录(凭据:{电子邮件:字符串,密码:字符串}){
返回此.httpClient.post(`${this.actionUrl}/login`,凭证)
.烟斗(
映射(令牌=>{
this.setJwtToken(tokens.accessToken);
this.setRefreshToken(tokens.refreshToken);
返回true;
})
);
}
刷新令牌(){
log('refreshToken()已调用');
const helper=新的JwtHelperService();
const email=helper.decodeToken(this.getJwtToken()).sub;
返回此.httpClient.post(`${this.actionUrl}/token/refresh`,{'refreshToken':localStorage.getItem(this.refresh_token),'email':email})
.烟斗(
映射(令牌=>{
log('refreshToken().pipe called()');
this.setJwtToken(tokens.accessToken);
this.setRefreshToken(tokens.refreshToken);
返回true;
})
);
}
注销(){
localStorage.removietem(这个.JWT_令牌);
localStorage.removietem(此.REFRESH\u令牌);
}
isTokenExpired():布尔值{
const helper=新的JwtHelperService();
return helper.isTokenExpired(this.getJwtToken());
}
getJwtToken():字符串{
返回localStorage.getItem(此.JWT_令牌);
}
setJwtToken(token:string){
setItem(this.JWT_令牌,令牌);
}
getRefreshToken():字符串{
返回localStorage.getItem(此.REFRESH\u令牌);
}
setRefreshToken(标记:字符串){
setItem(this.REFRESH\u令牌,令牌);
}
}

我认为问题就在这里:

else{
console.log('tokenexpired');
//这里!!!
this.authService.refreshToken()
.烟斗(
开关映射(结果=>{
log(`API返回:${result}`);
返回next.handle(this.attachtokentoquest(request,accessToken));
})
);
下一步返回。处理(请求);
}
}
您的是而不是返回的是