加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Angular2-jwt – AuthHttp,刷新令牌,将它们放在一起

发布时间:2020-12-17 17:04:55 所属栏目:安全 来源:网络整理
导读:这看起来好像我在这里圈,也许是因为使用了这么多订阅并且必须将它们链接在一起. 我希望能够刷新令牌,如果它已使用刷新令牌过期.这就是我所拥有的,如果可能的话,我真的很感激一个简单的工作示例. 总之,我如何确保AudienceService首先检查令牌是否有效,如果没
这看起来好像我在这里圈,也许是因为使用了这么多订阅并且必须将它们链接在一起.

我希望能够刷新令牌,如果它已使用刷新令牌过期.这就是我所拥有的,如果可能的话,我真的很感激一个简单的工作示例.

总之,我如何确保AudienceService首先检查令牌是否有效,如果没有,它会尝试使用刷新令牌刷新它,然后使用适当的令牌调用端点?

app.module.ts:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule,ReactiveFormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { RouterModule } from '@angular/router';
import { Http,RequestOptions } from '@angular/http';
import { ConfirmDialogModule,ListboxModule,PickListModule } from 'primeng/primeng';

import { AppComponent } from './app.component';
import { HeaderComponent } from './components/header/header.component';
import { HomeComponent } from './components/home/home.component';
import { ListAudiencesComponent } from './components/audiences/list-audiences/list-audiences.component';

import { AudienceService } from './services/audience.service';
import { LoggingService } from './services/logging.service';
import { RoleService } from './services/role.service';
import { AuthService } from './services/auth.service';
import { UserService } from './services/user.service';
import { AuthGuard } from './services/auth-guard.service'
import { AuthHttp,AuthConfig,provideAuth } from 'angular2-jwt';
import { ListRolesComponent } from './components/roles/list-roles/list-roles.component';
import { EditRoleAudiencesComponent } from './components/roles/edit-role-audiences/edit-role-audiences.component';
import { ModifyRoleComponent } from './components/roles/modify-role/modify-role.component';
import { LoginComponent } from './components/login/login.component';
import { UnauthorizedComponent } from './components/unauthorized/unauthorized.component';

export function authHttpServiceFactory(http: Http,options: RequestOptions) {
  return new AuthHttp(new AuthConfig({
    tokenName: 'token',tokenGetter: (() => sessionStorage.getItem('id_token')),globalHeaders: [{'Content-Type':'application/json'}],}),http,options);
}

@NgModule({
  declarations: [
    AppComponent,HeaderComponent,HomeComponent,ListAudiencesComponent,ListRolesComponent,EditRoleAudiencesComponent,ModifyRoleComponent,LoginComponent,UnauthorizedComponent
  ],imports: [
    BrowserModule,ConfirmDialogModule,FormsModule,HttpModule,PickListModule,ReactiveFormsModule,RouterModule.forRoot([
            { path: '',redirectTo: 'home',pathMatch: 'full' },{ path: 'home',component: HomeComponent },{ path: 'unauthorized',component: UnauthorizedComponent },{ path: 'audiences',component: ListAudiencesComponent,canActivate: [AuthGuard] },{ path: 'roles',component: ListRolesComponent,{ path: 'roles/modify/:name',component: ModifyRoleComponent,{ path: '**',redirectTo: 'home' }
        ]),],providers: [
    {
      provide: AuthHttp,useFactory: authHttpServiceFactory,deps: [Http,RequestOptions]
    },AudienceService,AuthGuard,AuthService,LoggingService,RoleService,UserService
    ],bootstrap: [AppComponent]
})
export class AppModule { }

auth.service.ts:

import { Injectable } from '@angular/core';
import { Http,Headers,RequestOptions,URLSearchParams } from '@angular/http';
import { environment } from '../../environments/environment';
import { tokenNotExpired } from 'angular2-jwt';

@Injectable()
export class AuthService {

  tokenEndpoint = environment.token_endpoint;
  constructor(private http: Http ) { }

  login(username: string,password: string) {
    let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' });
    let options = new RequestOptions({ headers: headers });
    let body = new URLSearchParams();
    body.set('username',username);
    body.set('password',password);
    body.set('client_id','099153c2625149bc8ecb3e85e03f0022');
    body.set('grant_type','password');

    console.log("Got here");

    return this.http.post(this.tokenEndpoint,body,options)
    .map(res => res.json())
    .subscribe(
        data => {
          localStorage.setItem('id_token',data.access_token);
          localStorage.setItem('refresh_token',data.refresh_token);
        },error => console.log(error)
      );
  }

  loggedIn() {
    if (tokenNotExpired()) {
      return true;
    } else {
      this.refreshToken()
      .subscribe(
          data => {
            if (data.error) {
              this.logout();
            } else {
              localStorage.setItem('id_token',data.access_token);
              localStorage.setItem('refresh_token',data.refresh_token);
              console.log("Token was refreshed.");
            }
          },error => this.logout(),() =>  {
            return tokenNotExpired();
          }
        );
    }
  }

  refreshToken() {
    let refToken = localStorage.getItem('refresh_token');
    if (refToken) {
      let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' });
      let options = new RequestOptions({ headers: headers });
      let body = new URLSearchParams();
      body.set('client_id','099153c2625149bc8ecb3e85e03f0022');
      body.set('grant_type','refresh_token');
      body.set('refresh_token',refToken);

      return this.http.post(this.tokenEndpoint,options)
      .map(res => res.json());
    } else {
      this.logout();
    }
  }

  tokenRequiresRefresh(): boolean {
    if (!this.loggedIn()) {
      console.log("Token refresh is required");
    }

    return !this.loggedIn();
  }

  logout() {
    localStorage.removeItem('id_token');
    localStorage.removeItem('refresh_token');
  }
}

audience.service.ts:

import 'rxjs/Rx';
import { Observable } from 'rxjs/Observable';
import { environment } from '../../environments/environment';
import { AuthHttp } from 'angular2-jwt';
import { AuthService } from './auth.service';

import { AddDeleteAudienceModel } from './AddAudienceModel';

@Injectable()
export class AudienceService {

  baseApiUrl = environment.api_endpoint;

  constructor(private http: Http,private authHttp: AuthHttp,private authService: AuthService) { }

  getAllAudiences()
  {
    if (this.authService.tokenRequiresRefresh()) {
      this.authService.refreshToken();
    }

    if (this.authService.loggedIn()) {
      return this.authHttp.get(this.baseApiUrl + 'audience/all').map(res => res.json());
    }
  }
}

解决方法

auth.service.ts

import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { Http,URLSearchParams } from '@angular/http';
import { environment } from '../../environments/environment';
import { tokenNotExpired,JwtHelper } from 'angular2-jwt';
import { Subject,Observable } from 'rxjs';

@Injectable()
export class AuthService {

  tokenEndpoint = environment.token_endpoint;
  requireLoginSubject: Subject<boolean>;
  tokenIsBeingRefreshed: Subject<boolean>;
  lastUrl: string;
  jwtHelper: JwtHelper = new JwtHelper();

  constructor(private http: Http,private router: Router) { 
    this.requireLoginSubject = new Subject<boolean>();
    this.tokenIsBeingRefreshed = new Subject<boolean>();
    this.tokenIsBeingRefreshed.next(false);
    this.lastUrl = "/home";
  }

  isUserAuthenticated() {

    if(this.loggedIn()) {
      this.requireLoginSubject.next(false);
      return true;
    } else {
      return false;
    }
  }

  login(username: string,'password');

    return this.http.post(this.tokenEndpoint,options).map(res => res.json());
  }

  loggedIn() {
    return tokenNotExpired();
  }

  addTokens(accessToken: string,refreshToken: string) {
    localStorage.setItem('id_token',accessToken);
    localStorage.setItem('refresh_token',refreshToken);
  }

  getRefreshTokenExpirationDate() {
    var token = localStorage.getItem('id_token');
    if (token) {
      let tokenExpDate = this.jwtHelper.getTokenExpirationDate(token);
      let sessionExpDate = new Date(tokenExpDate.getTime() + 4*60000);
      if (new Date() > sessionExpDate) {
        this.logout();
      }
      return sessionExpDate;
    }

    return null;
  }

  hasRefreshToken() {
    let refToken = localStorage.getItem('refresh_token');

    if (refToken == null) {
      this.logout();
    }

    return refToken != null;
  }

  refreshTokenSuccessHandler(data) {
    if (data.error) {
        console.log("Removing tokens.");
        this.logout();
        this.requireLoginSubject.next(true);
        this.tokenIsBeingRefreshed.next(false);
        this.router.navigateByUrl('/unauthorized');
        return false;
    } else {
        this.addTokens(data.access_token,data.refresh_token);
        this.requireLoginSubject.next(false);
        this.tokenIsBeingRefreshed.next(false);
        console.log("Refreshed user token");
    }
  }

  refreshTokenErrorHandler(error) {
    this.requireLoginSubject.next(true);
    this.logout();
    this.tokenIsBeingRefreshed.next(false);
    this.router.navigate(['/sessiontimeout']);
    console.log(error);
  }

  refreshToken() {
    let refToken = localStorage.getItem('refresh_token');
    //let refTokenId = this.jwtHelper.decodeToken(refToken).refreshTokenId;
    let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' });
    let options = new RequestOptions({ headers: headers });
    let body = new URLSearchParams();
    body.set('client_id','refresh_token');
    body.set('refresh_token',refToken);

    return this.http.post(this.tokenEndpoint,options)
      .map(res => res.json());
  }

  tokenRequiresRefresh(): boolean {
    if (!this.loggedIn()) {
      console.log("Token refresh is required");
    }

    return !this.loggedIn();
  }

  logout() {
    localStorage.removeItem('id_token');
    localStorage.removeItem('refresh_token');
    this.requireLoginSubject.next(true);
  }
}

AUTH-http.service.ts

import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import 'rxjs/Rx';
import { Observable } from 'rxjs/Observable';
import { environment } from '../../environments/environment';
import { AuthHttp } from 'angular2-jwt';
import { AuthService } from './auth.service';

@Injectable()
export class AuthHttpService {

  constructor(private authHttp: AuthHttp,private authService: AuthService,private router: Router) { }

  get(endpoint: string) {
    if (this.authService.tokenRequiresRefresh()) {
      this.authService.tokenIsBeingRefreshed.next(true);
      return this.authService.refreshToken().switchMap(
        (data) => {
          this.authService.refreshTokenSuccessHandler(data);
          if (this.authService.loggedIn()) {
            this.authService.tokenIsBeingRefreshed.next(false);
            return this.getInternal(endpoint);
          } else {
            this.authService.tokenIsBeingRefreshed.next(false);
            this.router.navigate(['/sessiontimeout']);
            return Observable.throw(data);
          }
        }
      ).catch((e) => {
        this.authService.refreshTokenErrorHandler(e);
        return Observable.throw(e);
      });
    }
    else {
      return this.getInternal(endpoint);
    }
  }

  post(endpoint: string,body: string) : Observable<any> {
    if (this.authService.tokenRequiresRefresh()) {
      this.authService.tokenIsBeingRefreshed.next(true);
      return this.authService.refreshToken().switchMap(
        (data) => {
          this.authService.refreshTokenSuccessHandler(data);
          if (this.authService.loggedIn()) {
            this.authService.tokenIsBeingRefreshed.next(false);
            return this.postInternal(endpoint,body);
          } else {
            this.authService.tokenIsBeingRefreshed.next(false);
            this.router.navigate(['/sessiontimeout']);
            return Observable.throw(data);
          }
        }
      ).catch((e) => {
        this.authService.refreshTokenErrorHandler(e);
        return Observable.throw(e);
      });
    }
    else {
      return this.postInternal(endpoint,body);
    }
  }

  private getInternal(endpoint: string) {
    return this.authHttp.get(endpoint);
  }

  private postInternal(endpoint: string,body: string) {
    return this.authHttp.post(endpoint,body);
  }

}

audience.service.ts

import { Injectable } from '@angular/core';
import 'rxjs/Rx';
import { Observable } from 'rxjs/Observable';
import { environment } from '../../environments/environment';
import { AuthHttpService } from './auth-http.service';

import { AddDeleteAudienceModel } from './AddAudienceModel';

@Injectable()
export class AudienceService {

  baseApiUrl = environment.api_endpoint;

  constructor(private authHttpService: AuthHttpService) { }

  getAllAudiences()
  {
    return this.authHttpService.get(this.baseApiUrl + 'audience/all').map(res => res.json());
  }

  addAudience(model: AddDeleteAudienceModel) {
    return this.authHttpService.post(this.baseApiUrl + 'audience',JSON.stringify(model)).map(res => res.json());
  }

  deleteAudience(model: AddDeleteAudienceModel) {
    return this.authHttpService.post(this.baseApiUrl + 'audience/delete',JSON.stringify(model)).map(res => res.json());
  }

}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读