[Ionic 2从入门到精通] 7.4 使用Facebook做授权验证

本节课中我们将整合Ionic Native中的Facebook插件,这样用户就可以在应用中获得认证,同时我们也可以做其他的事情例如获得用户信息。使用Facebook可以做大把的事情,我不会一一赘述,你还是看文档来的爽快些。
使用类似Facebook API类似的社交认证给我们带来了大量的好处。他帮助我们节省了时间去创建自己的认证后端服务(这里面包括了创建数据库,存储用户安全证书,操作密码重设逻辑等等),他帮助用户节省了创建新帐户的精力(他们只要一键就可以登录了),他提供了大量好用的数据和整合。这也不是说社交登录同源是最佳的认证方法,但是他的优点也很明显。
我们来研究一下如何设置Facebook插件然后将他整合到我们的应用中来。
重要:Facebook连接插件只会在真机上运行的时候在有效,如果你在桌面浏览器中运行的时候只会受到错误。用ionic run android或者ionic run ios代替ionic serve。如果你不确定怎么样才能让应用在你的设备上运行的话,先看一下本书的测试与调试部分。

设置Facebook应用

之前课程讲过,这个插件跟普通插件安装不一样。我们在安装的时候需要给插件提供一个App Name和一个App ID。所以我们需要在Facebook开发者平台创建一个应用,我们先来进行这一步。
首先你需要去developers.facebook.com如果没有帐号的话麻烦先注册一个。如果做完这一步的话,你应该可以看到如下:

Facebook开发者中心

点击My Apps然后Add a New App。选择iOS平台,然后在下一页上点击右上角的Skip and Create App ID按钮。填好Display Name(你的应用的名字,我们现在假定是CamperChat)并选择一个分类。然后点击Create App ID

Facebook开发者中心

现在你应该来到这样的一个屏幕。

Facebook开发者中心

你应该可以看到一个域叫做App ID,把他记在本子上因为我们马上就要用到他了。我们还需要一些设置。点击左边的Settings标签,在此我们将要添加使用平台,也就是iOS和Android。
我先现在可以添加iOS平台,但是Android平台在保存之前需要一个“key hash”。所以,我们现在不理他了,但是后面一定要回来加好因为没有他Android平台将无法运行。我们将在后面的构建章节学习如何为Android创建一个keystore文件和一个key hash,所以如果你现在就像完成这一步的话,可以现在就去到 Signing Android Applications部分。
点击Add Platform按钮然后选择iOS。你需要添加一个Bundle ID大概是这样的格式com.你的名字字母.你的项目或者com.你的公司.你的项目或者其他类似的东西。(译者:注意,一定要用字母,不要让我后悔把包名翻译了一下)同时你也需要确保将Single Sign On为‘Yes’。
同时需要确保你提供的Bundle ID和你的Ionic项目中的config.xml中的一致,所以确认一下你的config.xml下面这一行是否跟你的Facebook Apps Bundle ID匹配:

<widget id="com.yourname.yourproject" version="0.0.1"
    xmlns="http://www.w3.org/ns/widgets"
    xmlns:cdv="http://cordova.apache.org/ns/1.0">

在后面将你的Facebook app添加Android平台的时候也要提供相同的Bundle ID(他应该是在Google Play Package Name下面添加的)。
这是目前为止能做的,App NameApp ID在手,我们就可以给应用安装插件了。
重要:当你的应用准备上线的时候,记得将Facebook应用切换出开发模式,也就是去App Review标签页切换“Make Your App Public?”为“Yes”。

安装Facebook连接插件

在应用中安装此插件的话需要在项目目录内运行如下命令:

ionic plugin add cordova-plugin-facebook4 --save --variable APP_ID="123456789" --variable APP_NAME="myApplication"

记得将APP_ID和APP_NAME替换成你自己刚创建的的Facebook应用的。
重要:目前在Andoid上这个插件还有一个构建问题。根据你使用的版本这个可能也可能不会影响到你,但是如果构建Android失败的话,你可能需要去更改platforms/android/project.properties这一行:

cordova.system.library.1=com.facebook.android:facebook-android-sdk:4.4.0

设置认证

我们现在设置好了我们所需的东西,我们现在可以进行一点点编码工作了。整合Ionic Native的Facebook API其实非常简单,但是在这之前我们先创建我们的数据服务这样我们可以临时存储一些Facebook的相关值。数据服务主要是用于处理存储和获取我们的信息数据,但是由于我们需要存储一些来自Facebook的数据,所以很容易在这里确定好。
> 修改 src/providers/data.ts 为如下:

import { Injectable } from '@angular/core';

@Injectable()
export class Data {
    fbid: number;
    username: string;
    picture: string;

    constructor() {

    }
}

现在,我们要对登录页进行一些修改,以让用户在点击登录按钮的时候通过Facebook验证,而不是直接去到主页。
> 修改 src/pages/login/login.ts 的 login 函数如下:

login(): void {
    Facebook.login(['public_profile']).then((response) => {
        this.getProfile();
    }, (err) => {
        let alert = this.alertCtrl.create({
            title: 'Oops!',
            subTitle: 'Something went wrong, please try again later.',
            buttons: ['Ok']
        });

        alert.present();
    });
}

由于我们已经从Ionic Native导入过Facebook,我们现在可以访问Facebook对象了。我们调用login方法并传入我们请求的权限数组。我们只需要基本用户信息,所以我们只请求了用户的“public profile”权限,其他一些可以请求的权限例如:

  • 用户朋友
  • 用户兴趣
  • 用户简介
  • 用户位置
  • 用户打标签地方

还有其他一大堆,想要知道的话,点我吧login函数返回一个promise,所以我们给响应设置了一个处理器,如果成功的话我们触发之前设置的getProfile函数,这个函数将启动主页。如果不成功的话,我们创建一个警告框并展示给用户。
我们现在知道用户成功通过Facebook认证,他们也连接到我们的应用了,但是我们还是需要搞清楚一些细节。为了让他们能够用上我们的应用,我们需要他们的名字和照片,为了获取这些信息我们需要需改getProfile函数。
> 修改 src/pages/login/login.ts 的 getProfile 函数如下:

getProfile(): void {

    Facebook.api('/me?fields=id,name,picture', ['public_profile']).then((response) => {
        console.log(response);
        this.dataService.fbid = response.id;
        this.dataService.username = response.name;
        this.dataService.picture = response.picture.data.url;
        this.menu.enable(true);
        this.nav.setRoot(HomePage);
    },
    (err) => {
        console.log(err);
        let alert = this.alertCtrl.create({
        title: 'Oops!',
        subTitle: 'Something went wrong, please try again later.',
        buttons: ['Ok']
        });
        alert.present();
    });
}

现在我们想Facebook插件提供的api发起了调用。他允许我们与 Facebook Graph API 交互这就是我们能用Facebook做的所有事情了 -- 你可以做一些比较复杂的东西了但是我们只是用它来获取用户id,全名和展示图片。
第一个需要提供给api调用的参数是需要访问的终端,当前对我们来说就是/me因为我们想要摘掉当前登录用户的数据,我们添加了一个查询字符串包含了所有我们想要返回的数据域。我们也提供了一个权限数组然后等待响应。
如果响应成功的话我们使用我们的dataService存储得到的数据,然后我们启用侧滑菜单并转到主页。如果返回不成功的话,我们就要再次给用户展示一个警告框并把停留在登录页。
另一个需要用到的功能是Facebook API的登出方法。当用户登出我们的应用的时候我们也需要Facebook终止本次会话(session)(他不会登出facebook,只是再次使用的时候需要通过Facebook再次重新认证)。所以我们修养修改我们的logout函数。
> 修改 src/app/app.module.ts的logout方法如下:

logout(): void {
    this.menu.close();
    this.menu.enable(false);
    this.nav.setRoot(LoginPage);
    this.dataService.fbid = null;
    this.dataService.username = null;
    this.dataService.picture = null;
    Facebook.logout();
}

首先我们处理我们这边的事情。我们关闭了菜单并禁用了他,然后切换回登录页。我们重置了所有存放在我们数据服务是的Facebook数据,然后我们调用了Facebook API的logout方法。现在用户应该在咱们的应用中回到了登录页并且是未认证状态。
由于用户在认证的时候会有一点点的等待时间(就像我们获取用户资料的时候一样),我们想要给用户展示正在发生着一些事情,而不是应用卡死了。我们会用Ionic的LoadingController服务来完成这个。他允许我们在一个时期内停止和应用交互。
> 修改 src/pages/login/login.ts 为如下:

import { Component } from '@angular/core';
import { Platform, NavController, MenuController, AlertController, LoadingController } from 'ionic-angular';
import { Facebook } from 'ionic-native';
import { HomePage } from '../home/home';
import { Data } from '../../providers/data';

@Component({
    selector: 'page-login',
    templateUrl: 'login.html'
})
export class LoginPage {

    loading: any;

    constructor(public nav: NavController, public platform: Platform, public menu: MenuController, public dataService: Data, public alertCtrl:AlertController, public loadingCtrl: LoadingController) {
        this.loading = this.loadingCtrl.create({
            content: 'Authenticating...'
        });
        this.menu.enable(false);
    }

    login(): void {
        this.loading.present();

        Facebook.login(['public_profile']).then((response) => {
            this.getProfile();
        }, (err) => {
            let alert = this.alertCtrl.create({
                title: 'Oops!',
                subTitle: 'Something went wrong, please try again later.',
                buttons: ['Ok']
            });

            this.loading.dismiss();
            alert.present();

        });
    }

    getProfile(): void {
        Facebook.api('/me?fields=id,name,picture', ['public_profile']).then((response) => {
            console.log(response);
            this.dataService.fbid = response.id;
            this.dataService.username = response.name;
            this.dataService.picture = response.picture.data.url;
            this.menu.enable(true);
            this.loading.dismiss();
            this.nav.setRoot(HomePage);
        },
        (err) => {
            console.log(err);
            let alert = this.alertCtrl.create({
                title: 'Oops!',
                subTitle: 'Something went wrong, please try again later.',
                buttons: ['Ok']
            });
            
            this.loading.dismiss();
            alert.present();
        });
    }
}

注意在这里我们导入了LoadingController服务,我们在构造器中设置了一个“Authenticating...”信息。然后我们在调用登录方法的时候呈现了这个加载信息(就像Alert或者Modal一样)。然后,在响应的时候不管返回成功失败我们都关闭了加载中的信息。
这就是应用整合Facebook的全部了,但是可以通过Facebook API能做的远远不止这些。建议你看一下插件文档Facebook Graph API了解更多。
下节课中,我们来研究怎么样向屏幕上发送信息。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • 这个应用中我们将要实现一个实际的普通页面工作流,具体讲就是,一个登录页引导至主应用。在大部分需要用户登录验证的应用...
    老牛啃码阅读 742评论 0 0
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,580评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,391评论 25 707
  • 传统傣族节日服饰孕育着傣族人民对美好的向往,是傣族人民智慧的结晶。傣族节日服饰随着社会的不断发展正悄然的发生着改变...
    滚滚娱记阅读 6,890评论 0 2
  • 我不是你的新娘 但那是青春 昨晚凌晨一点,正准备进入梦乡,收到两条短信,睡意全无。 第一条:好久不见,想知道你过的...
    小晚笔记阅读 118评论 0 0