2017-10-11 26 views
1

我正在使用基於令牌的身份驗證,並且令牌已保存在數據庫中。Ionic 3如何確保在加載視圖之前獲取的db數據

當應用程序啓動時,我需要從數據庫中獲取令牌並在進行API調用之前使其可用。

什麼是做到這一點的最佳方式:

在組件:

ngOnit() { 
storage.get('token').then((val) => { 
    Make api call here 
}); 
} 

還是在共享服務:

getToken() { 
    return Promise((resolve, reject)=>{ 
     #if fetched once save in local var and resolve token 
     #or fetch from DB and resolve token 
    }) 
} 

// On Component 
this.sharedService.getToken().then((token)=>{ 
    //Make api call 
} 

有沒有什麼辦法可以確保DB令牌被取出並在視圖加載之前存儲在共享服務中? storage.get是'ES6承諾'

關注是在加載視圖升級到任何引導事件之前加載令牌的責任,因此onViewLoad不需要在每個組件中定義。

回答

3

我已經用這種方式實現了上面的用例。

我爲CRUD創建了ApiService,如下所示。該code是不言自明的,如果您需要更多信息,請讓我知道。

API-service.ts

import { Injectable, } from '@angular/core'; 
import { Http, Response } from '@angular/http'; 
import { Observable } from 'rxjs/Observable'; 
import { Headers, RequestOptions, BaseRequestOptions } from '@angular/http'; 
import { Storage } from '@ionic/storage'; 
import { Events } from 'ionic-angular'; 

@Injectable() 
export class ApiService { 

    constructor(private http: Http, private storage: Storage, private events: Events) { } 

    createHeader(headers: Headers) { 
     return new Promise((resolve, reject) => { 
      this.storage.get('loggedInUser') 
       .then((token: any) => { 
        if (token) headers.append('Authorization', 'token ' + token.token); 
        resolve(headers); 
       }, err => { 
        resolve(headers); 
       }); 
     }); 
    } 

    get(api) { 
     let header = new Headers(); 
     return Observable.fromPromise(this.createHeader(header)) 
      .map(() => { 
       let options = new BaseRequestOptions(); 
       options.withCredentials = true; 
       options.headers = header; 
       return options 
      }) 
      .switchMap((options) => this.http.get(api, options)) 
      .catch((err: Error | Response) => { 
       if (err instanceof Response && err.status === 401) { 
        this.events.publish('token-expiration'); 
       } 
       return Observable.throw(err); 
      }); 
    } 

    post(url, params): Observable<any> { 
     return new Observable(observer => { 
      let header = new Headers(); 
      this.createHeader(header) 
       .then(() => { 
        let options = new RequestOptions({ headers: header }); 
        this.http.post(url, params, options) 
         .subscribe(response => { 
          observer.next(response); 
          observer.complete(); 
         }, (e) => { 
          observer.error(e); 
         }); 
       }) 
     }) 
    } 

    delete(url) { 
     return new Observable(observer => { 
      let header = new Headers(); 
      this.createHeader(header) 
       .then(() => { 
        return this.http.delete(url, { headers: header, withCredentials: true }) 
         .subscribe(response => { 
          observer.next(response); 
          observer.complete(); 
         }); 
       }) 
     }); 
    } 

} 

在這裏,我已經創建loggedInUser存儲時登錄到app.It用戶也是provider如下所示。如下所示

社交login.ts

import { Injectable } from '@angular/core'; 
import { ApiService } from "../providers"; 
import { LocalCacheServiceProvider } from "../local-cache-service/local-cache-service"; 
import { UserService } from "../user-provider"; 
import { Storage } from '@ionic/storage'; 


@Injectable() 
export class SocialLoginProvider { 

    constructor(private apiService: ApiService, private localCacheService: LocalCacheServiceProvider, private userService: UserService, private storage: Storage) { 
    } 

    //login To App 
    loginToApp(url: string, data: string) { 
    this.apiService.post(url, { access_token: data }) 
     .map((res: any) => res.json()) 
     .subscribe(res => { 
     this.setUserLocally(res); 
     }); 
    } 

    //set User Locally 
    setUserLocally(user) { 
    this.localCacheService.clearAllKeys().then(() => { 
     this.userService.setLoggedInUser(user); 
     this.storage.set('loggedInUser', user); 
    }); 
    } 
} 

之後,我可以消耗上述服務(即ApiService)通過任何我的provider(對於CRUD操作)。

這是ArticleService

物品service.ts

import { Injectable } from '@angular/core'; 
import { Observable } from "rxjs/Observable"; 
import 'rxjs/add/operator/map'; 
import { config } from '../config/config'; 
import { ApiService } from './api-service'; 


@Injectable() 
export class ArticleService { 

    constructor(private apiService: ApiService) { 
    } 

    getBookById(id) { 
     return this.apiService.get(`${config.getBookById}${id}/`).map((res: any) => res.json()); 
    } 
} 

上述方法工作完全正常的me.Hope這種方法會幫助你too.If你需要更多的幫助,請讓我知道。

+0

我喜歡從api服務而不是每個組件獲取和添加令牌的概念。但是不直接從數據庫獲取令牌每次都是開銷,我可以使用它來存儲本地變量嗎? – joHN

+1

我認爲這是最好的,當我們考慮應用程序的安全性。我在這裏看不到任何性能問題。而且你也可以很好地處理令牌到期用例。參見'.catch((err:Error | Response)=> {if(例如Response && err.status === 401)this.events.publish('token-expiration'); } return Observable .throw(err); });' – Sampath

+0

是的,實際上我已經將'token'存儲在'localstorage'即'loggedInUser'中。 – Sampath

相關問題