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: '', 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实现定位.