HTML5手机APP开发入(5)

HTML5手机APP开发入(5)

回顾一下

HTML5手机APP开发入(4)

如何自定义Component,directive

HTML5手机APP开发入(3) 如何实现MVC的代码重构,自定义一个Provider Service,Injectable 依赖注入

HTML5手机APP开发入门(2)

利用ionic2 向导生成一个项目并开发一个简单的通讯录的APP

HTML5手机APP开发入门(1) ionic2+angular2 开发环境的配置

内容

完成一个登录验证的功能

这里我要向大家介绍一个第三方提供登录验证的云解决方案的,非常专业。并且支持Angular 2

https://auth0.com

Auth0是一家"身份验证即服务"提供商,旨在为开发人员提供简单易用的身份管理服务。为了保持灵活性和可扩展性,Auth0身份管理平台允许开发人员在身份验证和授权管道中增加自定义代码。而在一个多租户环境中,为了保证不同用户的自定义代码可以互不影响,就需要一种技术提供必要的数据隔离和资源利用保障。

步骤

注册一个auth0账号

登录https://manage.auth0.com/#/

新建一个application,这里需要做一些简单的配置

Allowed Callback URLs 设定你测试的客户端域名的url

配置auth0 客户端

Auth0提供了不同环境的Quick Start,我这边的环境就是ionic 2 + Angular 2

基本上一步一步照着做不会有问题。

1. Add the Auth0 Scripts and Install angular2-jwt

Install angular2-jwt with npm.

Add Lock in your index.html file and set the viewport.

添加javascript引用

2.修改app.ts

这里需要把用到类库angular2-jwt引用到项目中。同时还需要把Http也要加进来

注意:

providers:[DataService,

provide(AuthHttp, {

useFactory: (http) => {

return new AuthHttp(new AuthConfig({noJwtError: true}), http);

},

deps: [Http]

}),

AuthService],

3.新建一个authService用来实现登录验证

添加这些基础代码Quick Start都有提供照抄就可以了

Auth0提供很多自定开发功能,等有时间了慢慢研究,这里我们先简单的实现吧登录成功后把用户信息保存到本地,这样下次就可以不用在登录了

  1 import {Storage, LocalStorage} from  'ionic-angular';
  2 import {HTTP_PROVIDERS, Http} from 'angular2/http';
  3 import {Type} from 'angular2/core';
  4 import {AuthHttp, JwtHelper, tokenNotExpired,AuthConfig} from 'angular2-jwt';
  5 import {Injectable} from 'angular2/core';
  6 import {Observable} from 'rxjs/Rx';
  7 
  8 // Avoid name not found warnings
  9 declare var Auth0Lock;
 10 
 11 @Injectable()
 12 export class AuthService {
 13   jwtHelper: JwtHelper = new JwtHelper();
 14   lock  = new Auth0Lock('05VEtQMpSej5rgSgKor4XsaMaCJm8hLa', 'app1001.auth0.com');
 15   local: Storage = new Storage(LocalStorage);
 16   refreshSubscription: any;
 17   user: Object;
 18 
 19   constructor(private authHttp: AuthHttp) {
 20     // If there is a profile saved in local storage
 21    this.local.get('profile').then((profile)=>{
 22       if (profile) {
 23         this.user = JSON.parse(profile);
 24       }
 25     });
 26     //let profile = this.local.get('profile').map();
 27     // if (profile) {
 28     //   this.user = JSON.parse(profile);
 29     // }
 30   }
 31 
 32   public authenticated() {
 33     // Check if there's an unexpired JWT
 34     return tokenNotExpired();
 35   }
 36 
 37   public login() {
 38     // Show the Auth0 Lock widget
 39     this.lock.show({
 40       closable: false,
 41       authParams: {
 42         scope: 'openid offline_access',
 43         device: 'Mobile device'
 44       }
 45     }, (err, profile, token, accessToken, state, refreshToken) => {
 46       if (err) {
 47         alert(err);
 48       }
 49       // If authentication is successful, save the items
 50       // in local storage
 51       this.local.set('profile', JSON.stringify(profile));
 52       this.local.set('id_token', token);
 53       this.local.set('refresh_token', refreshToken);
 54       this.user = profile;
 55       // Schedule a token refresh
 56       this.scheduleRefresh();
 57     });
 58   }
 59 
 60   public logout() {
 61     this.local.remove('profile');
 62     this.local.remove('id_token');
 63     this.local.remove('refresh_token');
 64     this.user = null;
 65     // Unschedule the token refresh
 66     this.unscheduleRefresh();
 67   }
 68 
 69   public scheduleRefresh() {
 70     this.authHttp.tokenStream
 71         // .flatMap(token=>{
 72         //       let jwtIat = this.jwtHelper.decodeToken(token).iat;
 73         //       let jwtExp = this.jwtHelper.decodeToken(token).exp;
 74         //       let iat = new Date(0);
 75         //       let exp = new Date(0);
 76         //
 77         //       let delay = (exp.setUTCSeconds(jwtExp) - iat.setUTCSeconds(jwtIat));
 78         //       return Observable.interval(delay);
 79         // })
 80         .subscribe(
 81           data => {
 82           console.log(data)
 83            this.getNewJwt();
 84         },
 85       err => console.log(err),
 86       () => console.log('Complete')
 87       );
 88 
 89     // If the user is authenticated, use the token stream
 90     // provided by angular2-jwt and flatMap the token
 91     // let source = this.authHttp.tokenStream.flatMap(
 92     //   token => {
 93     //     // The delay to generate in this case is the difference
 94     //     // between the expiry time and the issued at time
 95     //     let jwtIat = this.jwtHelper.decodeToken(token).iat;
 96     //     let jwtExp = this.jwtHelper.decodeToken(token).exp;
 97     //     let iat = new Date(0);
 98     //     let exp = new Date(0);
 99     //
100     //     let delay = (exp.setUTCSeconds(jwtExp) - iat.setUTCSeconds(jwtIat));
101     //
102     //     return Observable.interval(delay);
103     //   });
104     //
105     // this.refreshSubscription = source.subscribe(() => {
106     //   this.getNewJwt();
107     // });
108   }
109 
110   public startupTokenRefresh() {
111     // If the user is authenticated, use the token stream
112     // provided by angular2-jwt and flatMap the token
113     // if (this.authenticated()) {
114     //   let source = this.authHttp.tokenStream.flatMap(
115     //     token => {
116     //       // Get the expiry time to generate
117     //       // a delay in milliseconds
118     //       let now: number = new Date().valueOf();
119     //       let jwtExp: number = this.jwtHelper.decodeToken(token).exp;
120     //       let exp: Date = new Date(0);
121     //       exp.setUTCSeconds(jwtExp);
122     //       let delay: number = exp.valueOf() - now;
123     //
124     //       // Use the delay in a timer to
125     //       // run the refresh at the proper time
126     //       return Observable.timer(delay);
127     //     });
128     //
129     //    // Once the delay time from above is
130     //    // reached, get a new JWT and schedule
131     //    // additional refreshes
132     //    source.subscribe(() => {
133     //      this.getNewJwt();
134     //      this.scheduleRefresh();
135     //    });
136     // }
137   }
138 
139   public unscheduleRefresh() {
140     // Unsubscribe fromt the refresh
141     if (this.refreshSubscription) {
142       this.refreshSubscription.unsubscribe();
143     }
144   }
145 
146   public getNewJwt() {
147     this.local.get('refresh_token').then(token=>{
148       this.lock.getClient().refreshToken(token,(err, delegationRequest) => {
149         if (err) {
150           alert(err);
151         }
152         console.log(delegationRequest);
153         this.local.set('id_token', delegationRequest.id_token);
154       });
155     });
156     // Get a new JWT from Auth0 using the refresh token saved
157     // in local storage
158     // let refreshToken = this.local.get('refresh_token')._result;
159     // this.lock.getClient().refreshToken(refreshToken, (err, delegationRequest) => {
160     //   if (err) {
161     //     alert(err);
162     //   }
163     //   this.local.set('id_token', delegationRequest.id_token);
164     // });
165   }
166 }

4.修改app.ts 实现登录后才能访问

如果没有登录就显示登录页面,而这登录页面auth0 都有模板不需要另外开发

 1 import {App, Platform,Storage, SqlStorage} from 'ionic-angular';
 2 import {StatusBar} from 'ionic-native';
 3 import {ListPage} from './pages/home/list';
 4 import {DataService} from './pages/services/dataService';
 5 import {tokenNotExpired, JwtHelper,AuthHttp, AuthConfig} from 'angular2-jwt';
 6 import {provide} from 'angular2/core';
 7 import {HTTP_PROVIDERS, Http} from 'angular2/http';
 8 import {Type} from 'angular2/core';
 9 import {AuthService} from './pages/services/auth';
10 
11 declare var Auth0Lock;
12 @App({
13   template: '<ion-nav [root]="rootPage"></ion-nav>',
14   providers:[DataService,
15           provide(AuthHttp, {
16                 useFactory: (http) => {
17                       return new AuthHttp(new AuthConfig({noJwtError: true}), http);
18                   },
19                 deps: [Http]
20                 }),
21               AuthService],
22   config: {} // http://ionicframework.com/docs/v2/api/config/Config/
23 })
24 export class MyApp {
25   rootPage: any = ListPage;
26   //lock = new Auth0Lock('T1wdQrDposGW5BisaKViC0Cu9CuxtR0c', 'towfeek.eu.auth0.com');
27   //jwtHelper: JwtHelper = new JwtHelper();
28   //location: Location;
29 
30   constructor(platform: Platform,private authService:AuthService) {
31     //var self = this;
32     platform.ready().then(() => {
33       // Okay, so the platform is ready and our plugins are available.
34       // Here you can do any higher level native things you might need.
35       StatusBar.styleDefault();
36       if(authService.authenticated()){
37         this.authService.login();
38       }
39 
40       // this.lock.show((err: string, profile: string, id_token: string) => {
41       //   if (err) {
42       //     throw new Error(err);
43       //   }
44       //
45       //   localStorage.setItem('profile', JSON.stringify(profile));
46       //   localStorage.setItem('id_token', id_token);
47       //
48       //   console.log(
49       //     this.jwtHelper.decodeToken(id_token),
50       //     this.jwtHelper.getTokenExpirationDate(id_token),
51       //     this.jwtHelper.isTokenExpired(id_token)
52       //   );
53       //});
54 
55 
56     });
57   }
58 }

5.RUN Test

当你运行app的时候系统就第一时间弹出登录页面,同时还有注册功能。是不是省了不少工作量

下次准备内容

打算在通讯录里调用一些手机的功能如何利用cordova-plugin-camera 调用拍照功能,利用cordova-plugin-geolocation实现定位.

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏腾讯技术工程官方号的专栏

科普:QUIC 协议原理分析

本文将主要介绍 QUIC 协议产生的背景和核心特性。

4.4K11
来自专栏非典型技术宅

Swift实践:使用CoreData完成上班签到小工具1. CoreData Stack的作用2.创建 CoreData Stack3. 一对多的关系4. 完成Demo,了解使用CoreData St

1243
来自专栏编程思想之路

Android7.1.1系统设置默认值大全

1,是否有默认值 在寻找一个开关的默认值时,首先要明白一点,该开关是否存在默认值,以及该开关状态是否有状态保存(一般状态存储在settings的db中)。 ...

70210
来自专栏Timhbw博客

Hexo-完全免费全平台搭建个人博客(2)-域名主题设置

2017-03-1011:01:58 发表评论 913℃热度 Hexo-完全免费全平台搭建个人博客(1)-整体搭建 上一篇文章把 Hexo 博客整体搭建一遍了...

42112
来自专栏*坤的Blog

Sublime Text3注册码供研究使用

2265
来自专栏Android源码框架分析

Android进程保活-自“裁”或者耍流氓

本篇文章是后台杀死系列的最后一篇,主要探讨一下进程的保活,Android本身设计的时候是非常善良的,它希望进程在不可见或者其他一些场景下APP要懂得主动释放,可...

6081
来自专栏tiane12

Navicat连接Oracle报unsupported server character set ZHS16GBK错误解决方法

1342
来自专栏闻道于事

Spring Security + JWT实现前后端分离权限认证

现在国内前后端很多公司都在使用前后端分离的开发方式,虽然也有很多人并不赞同前后端分离,比如以下这篇博客就很有意思:

2941
来自专栏加米谷大数据

技术分享 | kafka的使用场景以及生态系统

kafka的使用场景 今天介绍一些关于Apache kafka 流行的使用场景。这些领域的概述 消息 kafka更好的替换传统的消息系统,消息系统被用于各种场景...

9518
来自专栏禁心尽力

Shiro眼皮下玩ajax,玩出302 Found

1   public static String sendCode(String url,String encoded,String mobile,Stri...

2588

扫码关注云+社区

领取腾讯云代金券