Angular2 Http注册登录验证

jopen 4年前

前言

这是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的方法,并不是官方使用方法。

  1. Angular2 初探
  2. Angular2 表单验证
  3. Angular2之rxjs以及http的世界
  4. 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
</div>

后台程序

如果需要注册和登入的功能,我们首先需要一个后台服务。小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
</div>

这样做了之后会在3001端口做一个后台,实现注册以及登录的功能。主要的api如下:

POST /users
</div>

这个可以通过post注册一个新用户,在post的body里面需要包含username,password,extra。然后他会返回一个token,用户可以在后续验证中在header中包括这个token进行验证。

POST /sessions/create
</div>

这个可以让一个用户通过username和password进行login。在post的body里面需要包含username,password。同样返回一个token,用户也可以在后续验证中在header中包含这个token进行验证。

GET /api/random-quote
</div>

这个是一个api来取随机名言,这个不需要验证。

GET /api/protected/random-quote
</div>

这个是一个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 >
</div>

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]);
</div>

这样之后我们就可以在子模块中使用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')              );      }
</div>

如上面这个例子,我们在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;
</div>

然后就可以做post request来注册一个用户,我们可以来看一下angular2的http的api:

post(url: string, body: string, options?: RequestOptionsArgs) : Observable<Response>
</div>

其中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')         );      }
</div>

从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)
</div>

用户验证

刚刚保存在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')          );         }
</div>

首先我们从localstorage里面拿到保存的token,然后把它加入到header的Authorization中。通常token前面需要加bearer。然后和其他data call一样做get request。然后得到数据然后表示出来。

</div>

来自: http://gabriel0402.github.io/2016/01/18/angular-http-verification/