Angular2 Http注冊登錄驗證
前言
這是Angular2教程的第四部分,主要介紹Angular2的http service的使用,由于angular2的http包含很多內容,所以這一段博客會分三個部分介紹,第一部分是介紹如何在angular2中使用http,如何配置http的header,body, params等等。并且會介紹一個簡單的注冊登錄的例子。第二部分會介紹angular2的觀察者模式以及rxjs。第三部分會具體介紹如何在angular2中使用rxjs做restful data call的一些技巧。
由于Angular2的官方并沒有給出http的例子,而且api也還不完善,比如http還不支持form的header。所以小G在這里只是使用自己使用http的方法,并不是官方使用方法。
- Angular2 初探
- Angular2 表單驗證
- Angular2之rxjs以及http的世界
- Angular2 cheatsheet
參考資料
還是小G上個博客里面介紹的例子,鏈接在這:[Angular 2 quick start][2]。文件結構如下:
├──angular2/ │ │ │ ├──app/ │ │ ├──boot.ts │ │ ├──app.component.ts │ │ ├──http-test/ //依賴注入 用 │ │ ├──http-test.component.ts │ ├──index.html │ ├──package.json //用來安裝我們需要的庫, 以及node的一些命令 │ ├──tsconfig.json //用來配置typescript │ ├──style.css //這個playground的css
后臺程序
如果需要注冊和登入的功能,我們首先需要一個后臺服務。小G這里有一個很簡單的注冊登入的后臺: nodejs authentication 。這個后臺的主要功能是用JWT(Json Web Token)實現用戶注冊登入。現在web app的驗證方式主要為token驗證,所以小G打算使用這個驗證方式作為例子。
使用方法如下:
git clone https://github.com/auth0/nodejs-jwt-authentication-sample.git npm install node server.js
這樣做了之后會在3001端口做一個后臺,實現注冊以及登錄的功能。主要的api如下:
POST /users
這個可以通過post注冊一個新用戶,在post的body里面需要包含username,password,extra。然后他會返回一個token,用戶可以在后續驗證中在header中包括這個token進行驗證。
POST /sessions/create
這個可以讓一個用戶通過username和password進行login。在post的body里面需要包含username,password。同樣返回一個token,用戶也可以在后續驗證中在header中包含這個token進行驗證。
GET /api/random-quote
這個是一個api來取隨機名言,這個不需要驗證。
GET /api/protected/random-quote
這個是一個api來取隨機名言,需要使用注冊或登錄之后得到的token來進行驗證。
Angular2 Http Component
Angular2 Http 設置
在Angular2的官網上并沒有Http的配置的教程,如果你使用的是我之前的SystemJs的配置,就需要在index.html中加入html的src:
< script src="https://code.angularjs.org/2.0.0-beta.0/http.dev.js" >< /script >
Angular2暫時不能找到Http的module,還是需要加入源文件才能找到。但是有其他的tool比如webpack就可以把這些文件bundle起來可以直接在Component里面直接使用Http Provider。
在Dependency Injection里面我說過了service是一個singleton的模式,所以對于一個web app應該只需要一個http的service,所以我把他加入到bootstrap里面而不是在子模塊里面。在Angular2 BETA里面Http的service要加入Http Providers的dependency injection,這樣以后才能使用Http。
import {HTTP_PROVIDERS} from 'angular2/http' bootstrap(AppComponent,[HeroesService,HTTP_PROVIDERS]);
這樣之后我們就可以在子模塊中使用Http的service了。比如我寫的HttpTestComponent,可以在constructor中加入http使得在這個模塊中的所以函數都可以使用http service。
constructor(http:Http){ } getRandomQuote() { this.http.get('http://localhost:3001/api/random-quote') //1 .map(res => res.text()) //2 .subscribe( //3 data => this.randomQuote = data, err => this.logError(err), () => console.log('Random Quote Complete') ); }
如上面這個例子,我們在constructor中插入了http,然后在getRandomQuote函數中就可以使用http service。下面我們具體討論下Angular2 的http驗證。
用戶注冊
通常app的驗證方式是表單驗證,表單通常包含用戶名和密碼。在前面的博客中我提到了怎么做表單的驗證,這一章就不細說了。在template里面做好表單驗證的html mock up,然后就開始做基于http的驗證了。
首先是注冊的功能,從api里面可以看出,如果我們想要注冊一個用戶,我們需要提交用戶名和密碼。在這里簡單介紹下auth驗證方法。通常這種驗證是你做一個data call,data call通常是post。然后在data call的body中加入驗證信息,在這里就是用戶名和密碼,然后提交出去,后臺服務器會驗證這個信息,然后返回一個token。在后續的data call里面,需要在data call的header里面加入這個token來進行驗證。一般token會expire,所以一段時間過后需要重新驗證取得新的token。所以這是一個最簡單的http登錄模式。
對于第一次取得token的過程,一般只是一個簡單地驗證,所以只要在header里面加入‘Content-Type‘為’application/x-www-form-urlencoded‘的驗證信息即可。在javascript里面的http一般都支持header里面的form,但是angular2暫時還不支持,至少在RequestOptions里面我沒有看到相關的api。但其實這個很好實現,只是一個簡單的string,只要把所有的信息用string加起來即可:
var creds = "username=" + username + "&password=" + password;
然后就可以做post request來注冊一個用戶,我們可以來看一下angular2的http的api:
post(url: string, body: string, options?: RequestOptionsArgs) : Observable<Response>
其中RequestOptionsArgs 包括: url,method,search,headers。
所以在做post request的時候,我們首先需要一個url,可以從后臺的api里看出是 http://localhost:3001/users。 然后我們需要body,就是我們剛剛用用戶名和密碼構成的string。然后就是requestOptionsArgs,這個就是我們的data call需要的header。由于我們是提交一個表格的信息,所以‘Content-Type‘要設為為’application/x-www-form-urlencoded‘。具體如下:
url: http://localhost:3001/users
body: “username=” + username + “&password=” + password + “&extra=color”;
RequestOptionsArgs:’Content-Type’:’application/x-www-form-urlencoded’
根據這些信息,我們可以來做http data call。
register(data){ var username = data.username; var password = data.password; var creds = "username=" + username + "&password=" + password + "&extra=color"; var headers = new Headers(); headers.append('Content-Type', 'application/x-www-form-urlencoded'); this.http.post('http://localhost:3001/users', creds, { headers: headers }) .map(res => res.json()) .subscribe( data => console.log(data), err => this.logError(err), () => console.log('Register Complete') ); }
從http的api可以看出,他返回的是一個observable類型,這是一個觀察者類型,小G會在下一章具體介紹這個內容。可以先簡單介紹一下,在rxjs里面,一切都是流,當你建立一個observable之后,你等于新建了一個流,然后rxjs里面有很多函數,這些函數讓你可以合并,創建和過濾這些流。我們創建了這些流之后,我們并不需要去關注他,只有我們訂閱(subscribe)了這個流,我們才會得到相應的結果。比如當我們用Angular2新建一個post request,我們就新建了一個數據流,對于這個數據流,我們可以映射數據流里面的數據,比如返回的是res,我們可以把它映射成json形態。然后當我們訂閱這個數據流的時候,就可以看到數據流的變化。當然這么說會比較空洞,下一個rxjs我會具體結合圖來解釋這個基于數據流的觀察者模式。但目前我們只要知道我們做了post request,然后把返回的數據變成json格式。
就這樣我們完成了注冊的過程。而注冊之后的response會在data里面顯示。在response里會有驗證用的token,但是暫時還不用保存在localstorage。
用戶登錄
和上面的用戶注冊一樣,先用用戶名和密碼做post request,得到驗證的token。不同的是在登錄的時候我們要保存這個token。具體的方式在web app里面通常的方法是保存在localstorage里面,也就是通常瀏覽器的cookies&cache里面。同樣,post的api也發生了變化,所以如下:
url: http://localhost:3001/sessions/create
body: “username=” + username + “&password=” + password + “&extra=color”;
RequestOptionsArgs:’Content-Type’:’application/x-www-form-urlencoded’
當我們要保存token的時候,可以用:
localStorage.setItem('id_token', jwt)
用戶驗證
剛剛保存在localstorage里面的token就可以在以后的過程中放在header的Authorization中使用。如下面的代碼:
getSecretQuote() { var jwt = localStorage.getItem('id_token'); var authHeader = new Headers(); if(jwt) { authHeader.append('Authorization', 'Bearer ' + jwt); } this.http.get('http://localhost:3001/api/protected/random-quote', { headers: authHeader }) .map(res => res.text()) .subscribe( data => this.secretQuote = data, err => this.logError(err), () => console.log('Secret Quote Complete') ); }
首先我們從localstorage里面拿到保存的token,然后把它加入到header的Authorization中。通常token前面需要加bearer。然后和其他data call一樣做get request。然后得到數據然后表示出來。
來自: http://gabriel0402.github.io/2016/01/18/angular-http-verification/