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。然后得到数据然后表示出来。
</div>来自: http://gabriel0402.github.io/2016/01/18/angular-http-verification/