zoukankan      html  css  js  c++  java
  • 【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;
            }
        }
    }
  • 相关阅读:
    **RESTful API版本控制策略
    HTTP协议header标头详解
    $headers = $this->input->request_headers();返回请求头(header)数组
    ****Web API 版本控制的几种方式
    ****RESTful API 设计最佳实践(APP后端API设计参考典范)
    php怎么获取checkbox复选框的内容?
    Linux中Samba详细安装【转】
    linux中serial driver理解【转】
    Linux内核中进程上下文、中断上下文、原子上下文、用户上下文的理解【转】
    八、mini2440裸机程序之UART(2)UART0与PC串口通信【转】
  • 原文地址:https://www.cnblogs.com/sybboy/p/8779979.html
Copyright © 2011-2022 走看看