转载:Ionic 4 JWT Authentication Tutorial: Using Angular HttpClient with Node & Express.js Server
本教程演示如何使用ionic4和angular7创建登陆注册module。
将学习如何使用HttpClient发生Post请求到使用Node+Express.js创建的鉴权后台,使用RxJS Observable跟踪授权状态;
如何使用Ionic Storage module保存Express.js 返回的JWT信息,如token、过期时间等;
开始之前,需要确定Node.js和NPM安装到开发电脑上;
设置安装 Ionic CLI 4
npm install -g ionic
全局安装ionic一般需要管理员权限,win使用管理员权限的命令行,类linux使用sudo
创建Ionic 4 项目
命令行运行下面命令
ionic start ionic-auth-demo blank --type=angular
ionic4使用type指定前端框架为angular,后面可能会有vue,react,现在反正没有。ionic4的目标是不限制框架,甚至是原生js,jquery都可以用ionic创建混合移动app或者pwa
blank指定模板类型,这个模板只带一个叫home的页面,其他还有tabs。。。
如果你想指定其他cli还能干的事情,如安装cordova,安装免费Ionic Appflow SDK这些后面教程再讲。
等cli安装完依赖后,你就可以进入创建的目录,使用ionic serve运行体验app了,ionic serve会自动打开浏览器访问localhost:8100,如果愿意,加个-l,运行起来更酷哦
创建 Angular Module
modules是用来组织你的程序代码的。创建一个module封装鉴权功能的service和pages。
ionic generate module auth
运行上面命令将自动生成src/app/auth/auth.module.ts,修改代码如下:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
@NgModule({
declarations: [],
imports: [
CommonModule
]
})
export class AuthModule { }
auth Module只需要引入CommonModule,这个angular内建模块包含angular基本的一些 directives、pipes如:ngif,decimalPipe等
还需要再我们的root application模块(src/app/app.module.ts)引入auth模块。打开src/app/app.module.ts,再导入数组中添加AuthModule:
import { AuthModule } from './auth/auth.module';
@NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule,
AuthModule
],
providers: [
StatusBar,
SplashScreen,
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
],
bootstrap: [AppComponent]
})
export class AppModule {}
再导入HttpClient,发送http请求,FormsModule表单,Ionic Storage module本地存储
导入HttpClient
HttpClient是angular官方http客户端,所有我们需要在基于angular的ionic里导入。打开src/app/auth/auth.module.ts导入如下:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';
@NgModule({
declarations: [],
imports: [
CommonModule,
HttpClientModule
]
})
export class AuthModule { }
设置表单模块
angular为表单提供了强大的api,如基于模板的表单和reactive表单,这里我们用基于模板的表单,添加src/app/auth/auth.module.ts如下:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';
import { FormsModule } from '@angular/forms';
@NgModule({
declarations: [],
imports: [
CommonModule,
HttpClientModule,
FormsModule
]
})
export class AuthModule { }
设置存储模块
ionic team提供的存储模块可以在移动设备的浏览器本地存储,但是使用前必须先安装并引入
安装使用命令:
npm install --save @ionic/storage
写这教程的时候,版本是2.2.0.
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';
import { FormsModule } from '@angular/forms';
import { IonicStorageModule } from '@ionic/storage';
@NgModule({
declarations: [],
imports: [
CommonModule,
HttpClientModule,
FormsModule,
IonicStorageModule.forRoot()
]
})
export class AuthModule { }
创建Angular鉴权服务
设置了所有需要的设置后,我们可以创建鉴权服务了,用来封装HttpClient与Express server的通讯,如下命令创建:
ionic generate interface auth/user
生成src/app/auth/user.ts,编辑如下:
export interface User {
id: number;
name: string;
email: string;
password: string;
}
注意:在命令行里的auth/前缀告诉CLI在auth module里生成。
还需要生成服务器响应的接口,
ionic generate interface auth/auth-response
export interface AuthResponse {
user: {
id: number,
name: string,
email: string
} ,
access_token: string,
expires_in: number
}
具体怎么响应,在下一个部分,用Node+Express.js构建后台的时候再说。
ionic generate service auth/auth
生成auth服务,会产生两个文件:src/app/auth/auth.service.ts,src/app/auth/auth.service.spec.ts,多个spec的是用来自动化测试的,可以删除
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { tap } from 'rxjs/operators';
import { Observable, BehaviorSubject } from 'rxjs';
import { Storage } from '@ionic/storage';
import { User } from './user';
import { AuthResponse } from './auth-response';
定义变量
AUTH_SERVER_ADDRESS: string = 'http://localhost:3000';authSubject = new BehaviorSubject(false);
AUTH_SERVER_ADDRESS是后台地址,authSubject是用来订阅鉴权状态的Observable类型变量。
下一步构造函数中注入HttpClient和Storage
constructor(private httpClient: HttpClient, private storage: Storage) { }
使用HttpClient发送Post请求
register(user: User): Observable
{ return this.httpClient.post
(`${this.AUTH_SERVER_ADDRESS}/register`, user).pipe( tap(async (res: AuthResponse ) => {
if (res.user) {
await this.storage.set("ACCESS_TOKEN", res.access_token);
await this.storage.set("EXPIRES_IN", res.expires_in);
this.authSubject.next(true);
}
})
);
}
login(user: User): Observable
{ return this.httpClient.post(`${this.AUTH_SERVER_ADDRESS}/login`, user).pipe(
tap(async (res: AuthResponse) => {
if (res.user) {
await this.storage.set("ACCESS_TOKEN", res.access_token);
await this.storage.set("EXPIRES_IN", res.expires_in);
this.authSubject.next(true);
}
})
);
}
async logout() {
await this.storage.remove("ACCESS_TOKEN");
await this.storage.remove("EXPIRES_IN");
this.authSubject.next(false);
}
获取鉴权状态
最后添加isLoggedIn()方法用来检查用户登陆与否
isLoggedIn() {
return this.authSubject.asObservable();
}
创建Ionic Pages
创建页面使用如下命令:
ionic generate page auth/register
命令会自动更新src/app/app-routing.module.ts,添加如下路由:
{ path: 'register', loadChildren: './auth/register/register.module#RegisterPageModule' },
意思是可以直接通过http://localhost:8100/register访问注册页面
打开src/app/auth/register/register.page.ts文件,注入Authservice和Router
import { Component, OnInit } from '@angular/core';
import { Router } from "@angular/router";
import { AuthService } from '../auth.service';
@Component({
selector: 'app-register',
templateUrl: './register.page.html',
styleUrls: ['./register.page.scss'],
})
export class RegisterPage implements OnInit {
constructor(private authService: AuthService, private router: Router) { }
ngOnInit() {
}
}
添加register()方法
register(form) {
this.authService.register(form.value).subscribe((res) => {
this.router.navigateByUrl('home');
});
}
修改src/auth/register/register.page.html页面: