好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

【angular5项目积累总结】结合adal4实现http拦截器(token)

import { Injectable } from '@angular/core' ;
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpErrorResponse } from  '@angular/common/http' ;
import { Observable } from  "rxjs/Observable" ;
import { Adal4Service } from  'adal/adal4.service' ;
import { Router } from  '@angular/router' ;

@Injectable()
export class AuthInterceptor implements HttpInterceptor {

    constructor(
        private adalService: Adal4Service,
        private router: Router
    ) { }

    intercept(request: HttpRequest <any>, next: HttpHandler): Observable<HttpEvent<any>>  {
        const resource  =  this  .adalService.GetResourceForEndpoint(request.url);
        let authenticatedCall: Observable <HttpEvent<any>> ;
          if   (resource) {
              if  ( this  .adalService.userInfo.authenticated) {
                authenticatedCall  =  this  .adalService.acquireToken(resource)
                    .flatMap((token: string)  =>  {
                        request  =  request.clone({
                            setHeaders: {
                                Authorization: `Bearer ${token}`
                            }
                        });
                          return  next.handle(request). catch ( this  .handleError);
                    });
            }
              else   {
                  this  .adalService.refreshDataFromCache();
                authenticatedCall  = Observable. throw ( new  Error('User Not Authenticated.' ));
            }
        }
          else  { authenticatedCall = next.handle(request). catch ( this  .handleError); }

          return   authenticatedCall;
    }

    private handleError(err: HttpErrorResponse): Observable <any>  {        
          if  (err.status === 401 || err.status === 403 ) {
            console.log(err.message);
              this .router.navigate(['dataService' ], {});
              return   Observable.of(err.message);
        }
          //   handle your auth error or rethrow 
         return  Observable. throw  (err);
    }
} 

 Adal4Interceptor

import { Injectable } from '@angular/core' ;
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from  '@angular/common/http' ;
import { Observable } from  'rxjs/Observable' ;

import { Adal4Service } from  './adal4.service' ;

@Injectable()
export class Adal4Interceptor implements HttpInterceptor {
    constructor(public adal4Service: Adal4Service) { }
    intercept(request: HttpRequest <any>, next: HttpHandler): Observable<HttpEvent<any>>  {

        request  =  request.clone({
            setHeaders: {
                Authorization: `Bearer ${  this  .adal4Service.userInfo.token}`
            }
        });
          return   next.handle(request);
    }
} 

 

adal4service

import { Injectable } from '@angular/core' ;
import { Observable } from  'rxjs' ;
import { Adal4User } from  './adal4-user' ;
import  * as adalLib from 'adal-angular' ;
import { adal } from  'adal-angular' ;

import User  =  adal.User;


@Injectable()
export class Adal4Service {

  
  private adalContext: adal.AuthenticationContext;

 
  private adal4User: Adal4User  =  {
    authenticated:   false  ,
    username:  '' ,
    error:  '' ,
    token:  '' ,
    profile: {}
  };

  
  constructor() { }

  
  public init(configOptions: adal.Config) {
      if  (! configOptions) {
        throw   new  Error('You must set config, when calling init.' );
    }

    const existingHash  =  window.location.hash;

    let pathDefault  =  window.location.href;
      if   (existingHash) {
      pathDefault  = pathDefault.replace(existingHash, '' );
    }

    configOptions.redirectUri  = configOptions.redirectUri ||  pathDefault;
    configOptions.postLogoutRedirectUri  = configOptions.postLogoutRedirectUri ||  pathDefault;

      this .adalContext =  adalLib.inject(configOptions);

    window.AuthenticationContext  =  this  .adalContext.constructor;

      this .updateDataFromCache( this  .adalContext.config.loginResource);
  }

 
  public get config(): adal.Config {
      return   this  .adalContext.config;
  }

  
  public get userInfo(): Adal4User {
      return   this  .adal4User;
  }

 
  public login():   void   {
      this  .adalContext.login();
  }


  public loginInProgress():   boolean   {
      return   this  .adalContext.loginInProgress();
  }

  public logOut():   void   {
      this  .adalContext.logOut();
  }

  
  public handleWindowCallback():   void   {
    const hash  =  window.location.hash;
      if  ( this  .adalContext.isCallback(hash)) {
      const requestInfo  =  this  .adalContext.getRequestInfo(hash);
        this  .adalContext.saveTokenFromHash(requestInfo);
        if  (requestInfo.requestType ===  this  .adalContext.REQUEST_TYPE.LOGIN) {
          this .updateDataFromCache( this  .adalContext.config.loginResource);

      }   else   if  (requestInfo.requestType ===  this  .adalContext.REQUEST_TYPE.RENEW_TOKEN) {
          this .adalContext.callback =  window.parent.callBackMappedToRenewStates[requestInfo.stateResponse];
      }

        if   (requestInfo.stateMatch) {
          if  ( typeof   this .adalContext.callback === 'function' ) {
            if  (requestInfo.requestType ===  this  .adalContext.REQUEST_TYPE.RENEW_TOKEN) {
              if  (requestInfo.parameters['access_token' ]) {
                this .adalContext.callback( this .adalContext._getItem( this  .adalContext.CONSTANTS.STORAGE.ERROR_DESCRIPTION)
                , requestInfo.parameters[ 'access_token' ]);
            }
              else   if  (requestInfo.parameters['error' ]) {
                this .adalContext.callback( this .adalContext._getItem( this .adalContext.CONSTANTS.STORAGE.ERROR_DESCRIPTION),  null  );
                this .adalContext._renewFailed =  true  ;
            }
          }
        }
      }
    }

      if   (window.location.hash) {
      window.location.href  = window.location.href.replace(window.location.hash, '' );
    }
  }

  
  public getCachedToken(resource: string): string {
      return   this  .adalContext.getCachedToken(resource);
  }

  
  public acquireToken(resource: string) {
    const _this  =  this  ;   

    let errorMessage: string;
      return  Observable.bindCallback(acquireTokenInternal,  function   (token: string) {
        if  (!token &&  errorMessage) {
          throw   (errorMessage);
      }
        return   token;
    })();

      function   acquireTokenInternal(cb: any) {
      let s: string  =  null  ;

      _this.adalContext.acquireToken(resource, (error: string, tokenOut: string)  =>  {
          if   (error) {
          _this.adalContext.error( 'Error when acquiring token for resource: ' +  resource, error);
          errorMessage  =  error;
          cb( <string> null  );
        }   else   {
          cb(tokenOut);
          s  =  tokenOut;
        }
      });
        return   s;
    }
  }

 
  public getUser(): Observable <any>  {
      return  Observable.bindCallback((cb: (u: adal.User) => User) =>  {
        this .adalContext.getUser( function   (error: string, user: adal.User) {
          if   (error) {
            this .adalContext.error('Error when getting user' , error);
          cb(  null  );
        }   else   {
          cb(user);
        }
      });
    })();
  }

 
  public clearCache():   void   {
      this  .adalContext.clearCache();
  }


  public clearCacheForResource(resource: string):   void   {
      this  .adalContext.clearCacheForResource(resource);
  }

  public info(message: string):   void   {
      this  .adalContext.info(message);
  }

 
  public verbose(message: string):   void   {
      this  .adalContext.verbose(message);
  }

  public GetResourceForEndpoint(url: string): string {
      return   this  .adalContext.getResourceForEndpoint(url);
  }


  public refreshDataFromCache() {
      this .updateDataFromCache( this  .adalContext.config.loginResource);
  }


  private updateDataFromCache(resource: string):   void   {
    const token  =  this  .adalContext.getCachedToken(resource);
      this .adal4User.authenticated = token !==  null  && token.length > 0 ;
    const user  =  this .adalContext.getCachedUser() || { userName: '' , profile: undefined };
      if   (user) {
        this .adal4User.username =  user.userName;
        this .adal4User.profile =  user.profile;
        this .adal4User.token =  token;
        this .adal4User.error =  this  .adalContext.getLoginError();
    }   else   {
        this .adal4User.username = '' ;
        this .adal4User.profile =  {};
        this .adal4User.token = '' ;
        this .adal4User.error = '' ;
    }
  };
} 

Adal4User

 export class Adal4User {
    authenticated:   boolean  ;
    username: string;
    error: string;
    profile: any;
    token: string;
} 

adal-angular.d

declare  var   AuthenticationContext: adal.AuthenticationContextStatic;

declare namespace adal {

    interface Config {
        tenant ? : string;
        clientId: string;
        redirectUri ? : string;
        instance ? : string;
        endpoints ? : any; 
        popUp ?:  boolean  ;
        localLoginUrl ? : string;
        displayCall ?: (urlNavigate: string) =>  any;
        postLogoutRedirectUri ? : string; 
        cacheLocation ? : string;
        anonymousEndpoints ? : string[];
        expireOffsetSeconds ? : number;
        correlationId ? : string;
        loginResource ? : string;
        resource ? : string;
        extraQueryParameter ? : string;
        navigateToLoginRequestUrl ?:  boolean  ;
    }

    
    interface User {
        userName: string;
        profile: any;
    }

    interface RequestInfo {
        valid:   boolean  ;
        parameters: any;
        stateMatch:   boolean  ;
        stateResponse: string;
        requestType: string;
    }

    interface AuthenticationContextStatic {
          new   (config: Config): AuthenticationContext;
    }

   
    interface AuthenticationContext {

        CONSTANTS: any;

        REQUEST_TYPE: {
            LOGIN: string,
            RENEW_TOKEN: string,
            UNKNOWN: string
        };

        callback: any;

        _getItem: any;

        _renewFailed: any;

        instance: string;
        config: Config;

        login():   void  ;
        
        loginInProgress():   boolean  ;
        
        getCachedToken(resource: string): string;
      
        getCachedUser(): User;

        registerCallback(expectedState: string, resource: string, callback: (message: string, token: string)  => any):  void  ;

        acquireToken(resource: string, callback: (message: string, token: string)  => any):  void  ;
       
        promptUser(urlNavigate: string):   void  ;

        clearCache():   void  ;
        
        clearCacheForResource(resource: string):   void  ;

        logOut():   void  ;
        
        getUser(callback: (message: string, user ?: User) => any):  void  ;

        isCallback(hash: string):   boolean  ;

        getLoginError(): string;

        getRequestInfo(hash: string): RequestInfo;

        saveTokenFromHash(requestInfo: RequestInfo):   void  ;

        getResourceForEndpoint(endpoint: string): string;

        handleWindowCallback():   void  ;

        log(level: number, message: string, error: any):   void  ;
        error(message: string, error: any):   void  ;
        warn(message: string):   void  ;
        info(message: string):   void  ;
        verbose(message: string):   void  ;
    }
}

interface Window {
    AuthenticationContext: any;
    callBackMappedToRenewStates: any;
} 

logged-in.guard

import { Injectable } from '@angular/core' ;
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from  '@angular/router' ;
import { Adal4Service } from  './adal4.service' ;

@Injectable()
export class LoggedInGuard implements CanActivate{
  
    constructor(private adalService: Adal4Service,
        ) {
    }

    canActivate(
        route: ActivatedRouteSnapshot,
        state: RouterStateSnapshot
    ):   boolean   {
          this  .adalService.handleWindowCallback();
          if  ( this  .adalService.userInfo.authenticated) {
              return   true  ;
        }   else   {
              this  .adalService.login();
              return   false  ;
        }
    }
} 

 

查看更多关于【angular5项目积累总结】结合adal4实现http拦截器(token)的详细内容...

  阅读:64次