第三方登录 是指用户使用第三方平台(如 Google、Facebook、Apple、Twitter 等)的账户进行应用登录。这种方式简化了用户注册和登录流程,提高了用户体验,并利用第三方平台提供的身份验证机制来确保安全性。React Native 提供了多种方式来实现第三方登录,包括使用第三方库(如 react-native-google-signin
, react-native-facebook-login
, react-native-apple-authentication
)和调用原生模块。本章节将详细介绍如何使用 react-native-google-signin
和 react-native-facebook-login
库来实现 Google 和 Facebook 第三方登录。
5.1 第三方登录概述
第三方登录的主要流程包括:
- 用户选择第三方平台进行登录: 用户选择使用 Google、Facebook 等第三方平台的账户进行登录。
- 应用调用第三方平台的 SDK 进行身份验证: 应用通过第三方平台的 SDK 或 API 发起身份验证请求。
- 用户授权: 用户在第三方平台授权应用访问其账户信息。
- 获取用户信息: 应用从第三方平台获取用户的身份信息(如用户 ID、姓名、邮箱等)。
- 登录完成: 应用根据获取到的用户信息完成登录流程。
常见的第三方登录平台:
- Google Sign-In
- Facebook Login
- Apple Sign-In
- Twitter Login
- GitHub Login
- 微信登录
- QQ 登录
React Native 提供了多种第三方库来简化第三方登录的实现:
react-native-google-signin
: 用于实现 Google 登录。react-native-facebook-login
: 用于实现 Facebook 登录。react-native-apple-authentication
: 用于实现 Apple 登录。react-native-twitter-signin
: 用于实现 Twitter 登录。react-native-wechat
: 用于实现微信登录。
本章节将重点介绍如何使用 react-native-google-signin
和 react-native-facebook-login
库来实现 Google 和 Facebook 第三方登录。
5.2 使用 react-native-google-signin
实现 Google 登录
react-native-google-signin
是一个流行的第三方库,用于实现 Google 登录功能。
5.2.1 安装 react-native-google-signin
npm install @react-native-google-signin/google-signin
链接原生依赖(React Native 0.60 及以上版本自动链接):
cd ios
pod install
cd ..
5.2.2 配置 Google API
-
创建 Google Cloud 项目:
前往 Google Cloud Console,创建一个新项目。
-
启用 Google Sign-In API:
在 API 库中,启用 Google Sign-In API。
-
配置 OAuth 同意屏幕:
配置 OAuth 同意屏幕,设置应用名称、支持邮箱等。
-
创建 OAuth 2.0 客户端 ID:
在凭据页面,创建一个 OAuth 客户端 ID,选择 Android 或 iOS 平台,并填写应用包名和 SHA-1 指纹。
-
配置
google-services.json
和GoogleService-Info.plist
:下载
google-services.json
文件,并将其放置在android/app
目录下。下载
GoogleService-Info.plist
文件,并将其添加到 Xcode 项目中。
5.2.3 基本用法
示例:
import React from 'react';
import { View, Button, StyleSheet, Alert } from 'react-native';
import { GoogleSignin, GoogleSigninButton, statusCodes } from '@react-native-google-signin/google-signin';const GoogleLoginExample = () => {const [user, setUser] = React.useState(null);React.useEffect(() => {// 配置 Google Sign-InGoogleSignin.configure({webClientId: 'YOUR_WEB_CLIENT_ID', // 从 Google API Console 获取offlineAccess: true, // 是否支持离线访问hostedDomain: '', // 指定域名(可选)forceCodeForRefreshToken: true, // 是否强制刷新 tokenaccountName: '', // 指定账户名(可选)});}, []);const handleSignIn = async () => {try {await GoogleSignin.hasPlayServices();const userInfo = await GoogleSignin.signIn();setUser(userInfo);console.log('用户信息:', userInfo);} catch (error) {if (error.code === statusCodes.SIGN_IN_CANCELLED) {console.log('用户取消登录');} else if (error.code === statusCodes.IN_PROGRESS) {console.log('登录操作正在进行中');} else {console.error('登录错误:', error);}}};const handleSignOut = async () => {try {await GoogleSignin.signOut();setUser(null);console.log('用户已登出');} catch (error) {console.error('登出错误:', error);}};return (<View style={styles.container}>{user ? (<View><Text style={styles.text}>Hello, {user.user.name}</Text><Button title="登出" onPress={handleSignOut} /></View>) : (<GoogleSigninButtonstyle={styles.button}size={GoogleSigninButton.Size.Wide}color={GoogleSigninButton.Color.Dark}onPress={handleSignIn}/>)}</View>);
};const styles = StyleSheet.create({container: {flex: 1,justifyContent: 'center',alignItems: 'center',padding: 20,},button: {width: 200,height: 50,},text: {fontSize: 18,marginBottom: 10,},
});export default GoogleLoginExample;
解释:
GoogleSignin.configure
方法: 配置 Google Sign-In,包括webClientId
(从 Google API Console 获取)。GoogleSignin.hasPlayServices
方法: 检查设备是否安装了 Google Play 服务。GoogleSignin.signIn
方法: 发起 Google 登录请求。GoogleSignin.signOut
方法: 登出用户。
5.2.4 获取用户信息
react-native-google-signin
返回的用户信息包含以下字段:
id
: 用户唯一标识符。name
: 用户姓名。email
: 用户邮箱。photo
: 用户头像 URL。idToken
: 身份验证 token。accessToken
: 访问 token。
示例:
const handleSignIn = async () => {try {await GoogleSignin.hasPlayServices();const userInfo = await GoogleSignin.signIn();console.log('用户信息:', userInfo);// 发送用户信息到服务器进行身份验证} catch (error) {// 处理错误}
};
5.2.5 处理登录状态
可以通过 isSignedIn
方法检查用户是否已经登录。
示例:
const checkLoginStatus = async () => {const isSignedIn = await GoogleSignin.isSignedIn();if (isSignedIn) {const userInfo = await GoogleSignin.signInSilently();setUser(userInfo);}
};
5.3 使用 react-native-facebook-login
实现 Facebook 登录
react-native-facebook-login
是一个流行的第三方库,用于实现 Facebook 登录功能。
5.3.1 安装 react-native-facebook-login
npm install react-native-facebook-login
链接原生依赖(React Native 0.60 及以上版本自动链接):
cd ios
pod install
cd ..
5.3.2 配置 Facebook API
-
创建 Facebook 应用:
前往 Facebook Developers,创建一个新应用。
-
配置 OAuth 重定向 URI:
在 Facebook 应用设置中,配置 OAuth 重定向 URI。
-
配置
Info.plist
(iOS):在
Info.plist
文件中添加以下内容:<key>CFBundleURLTypes</key> <array><dict><key>CFBundleURLSchemes</key><array><string>fbYOUR_FB_APP_ID</string></array></dict> </array> <key>FacebookAppID</key> <string>YOUR_FB_APP_ID</string> <key>FacebookDisplayName</key> <string>YOUR_APP_NAME</string>
-
配置
AndroidManifest.xml
(Android):在
AndroidManifest.xml
文件中添加以下内容:<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/>
在
res/values/strings.xml
文件中添加:<string name="facebook_app_id">YOUR_FB_APP_ID</string>
5.3.3 基本用法
示例:
import React from 'react';
import { View, Button, StyleSheet, Alert } from 'react-native';
import { LoginManager, AccessToken } from 'react-native-facebook-login';const FacebookLoginExample = () => {const handleLogin = () => {LoginManager.logInWithPermissions(['public_profile', 'email']).then((result) => {if (result.isCancelled) {console.log('用户取消登录');} else {AccessToken.getCurrentAccessToken().then((data) => {const token = data.accessToken;fetch('https://graph.facebook.com/v12.0/me?fields=id,name,email&access_token=' + token).then((response) => response.json()).then((json) => {console.log('用户信息:', json);// 发送用户信息到服务器进行身份验证}).catch((error) => {console.error('获取用户信息失败:', error);});});}},(error) => {console.error('登录错误:', error);});};const handleLogout = () => {// Facebook SDK 不提供直接登出方法// 可以清除本地存储的用户信息Alert.alert('登出', 'Facebook SDK 不提供直接登出方法');};return (<View style={styles.container}><Button title="Facebook 登录" onPress={handleLogin} /><Button title="登出" onPress={handleLogout} /></View>);
};const styles = StyleSheet.create({container: {flex: 1,justifyContent: 'center',alignItems: 'center',padding: 20,},
});export default FacebookLoginExample;
解释:
LoginManager.logInWithPermissions
方法: 发起 Facebook 登录请求,并请求指定权限。AccessToken.getCurrentAccessToken
方法: 获取当前用户的访问 token。fetch
请求: 使用 Graph API 获取用户信息。
5.3.4 获取用户信息
可以通过 Facebook Graph API 获取用户信息,如用户 ID、姓名、邮箱等。
示例:
const getUserInfo = (token) => {fetch('https://graph.facebook.com/v12.0/me?fields=id,name,email&access_token=' + token).then((response) => response.json()).then((json) => {console.log('用户信息:', json);// 发送用户信息到服务器进行身份验证}).catch((error) => {console.error('获取用户信息失败:', error);});
};
5.3.5 处理登录状态
Facebook SDK 本身不提供直接的登出方法,但可以通过清除应用的登录状态来实现登出功能。以下是如何处理登录状态的详细说明:
5.3.5.1 清除登录状态
要登出用户,通常需要清除应用中的登录状态。由于 react-native-facebook-login
不提供直接的登出方法,可以通过以下几种方式来实现:
-
清除 Access Token:
使用
AccessToken
模块清除存储的 Access Token。import { AccessToken } from 'react-native-facebook-login';const handleLogout = async () => {try {await AccessToken.setCurrentAccessToken(null);Alert.alert('登出成功', '您已成功登出 Facebook');} catch (error) {console.error('登出失败:', error);Alert.alert('登出失败', '无法清除登录状态');} };
解释:
AccessToken.setCurrentAccessToken(null)
方法用于清除存储的 Access Token。- 清除 Token 后,应用将认为用户已登出。
-
清除应用缓存(可选):
有时,清除 Access Token 可能不足以完全登出用户,尤其是在应用缓存中仍然保留用户信息的情况下。此时,可以选择清除应用的缓存。
import { AsyncStorage } from 'react-native';const clearAppCache = async () => {try {await AsyncStorage.clear();console.log('应用缓存已清除');} catch (error) {console.error('清除缓存失败:', error);} };const handleLogout = async () => {try {await AccessToken.setCurrentAccessToken(null);await clearAppCache();Alert.alert('登出成功', '您已成功登出 Facebook');} catch (error) {console.error('登出失败:', error);Alert.alert('登出失败', '无法清除登录状态');} };
解释:
AsyncStorage.clear()
方法用于清除应用的所有存储数据,包括缓存的用户信息。
-
调用 Facebook SDK 的登出(高级):
如果需要更彻底的登出,可以调用 Facebook SDK 的原生登出方法。这需要使用原生代码进行扩展。
示例(iOS):
#import <FBSDKLoginKit/FBSDKLoginKit.h>// 在 AppDelegate.m 中添加一个方法 - (void)logoutFacebook {[[FBSDKLoginManager new] logOut]; }
然后在 React Native 中通过原生模块调用这个方法。
示例(JavaScript):
import { NativeModules } from 'react-native';const { RNFacebookLogin } = NativeModules;const handleLogout = async () => {try {await AccessToken.setCurrentAccessToken(null);RNFacebookLogin.logoutFacebook();Alert.alert('登出成功', '您已成功登出 Facebook');} catch (error) {console.error('登出失败:', error);Alert.alert('登出失败', '无法清除登录状态');} };
注意: 这种方法需要使用原生代码进行扩展,适用于高级用户。
5.3.5.2 检查登录状态
可以通过 AccessToken.getCurrentAccessToken
方法检查用户是否已经登录。
示例:
import React, { useEffect, useState } from 'react';
import { View, Text, Button, StyleSheet, Alert } from 'react-native';
import { AccessToken } from 'react-native-facebook-login';const FacebookLoginExample = () => {const [isLoggedIn, setIsLoggedIn] = useState(false);const [userInfo, setUserInfo] = useState(null);useEffect(() => {const checkLoginStatus = async () => {const token = await AccessToken.getCurrentAccessToken();if (token) {setIsLoggedIn(true);fetchUserInfo(token.accessToken);}};checkLoginStatus();}, []);const fetchUserInfo = async (token) => {try {const response = await fetch(`https://graph.facebook.com/v12.0/me?fields=id,name,email&access_token=${token}`);const json = await response.json();setUserInfo(json);console.log('用户信息:', json);} catch (error) {console.error('获取用户信息失败:', error);}};const handleLogin = () => {// 登录逻辑};const handleLogout = async () => {try {await AccessToken.setCurrentAccessToken(null);await clearAppCache();setIsLoggedIn(false);setUserInfo(null);Alert.alert('登出成功', '您已成功登出 Facebook');} catch (error) {console.error('登出失败:', error);Alert.alert('登出失败', '无法清除登录状态');}};const clearAppCache = async () => {try {await AsyncStorage.clear();console.log('应用缓存已清除');} catch (error) {console.error('清除缓存失败:', error);}};return (<View style={styles.container}>{isLoggedIn ? (<View><Text style={styles.text}>Hello, {userInfo.name}</Text><Button title="登出" onPress={handleLogout} /></View>) : (<Button title="Facebook 登录" onPress={handleLogin} />)}</View>);
};const styles = StyleSheet.create({container: {flex: 1,justifyContent: 'center',alignItems: 'center',padding: 20,},text: {fontSize: 18,marginBottom: 10,},
});export default FacebookLoginExample;
解释:
- 检查登录状态: 通过
AccessToken.getCurrentAccessToken
方法检查用户是否已经登录。 - 获取用户信息: 如果用户已登录,可以通过 Graph API 获取用户信息。
- 登出: 调用
AccessToken.setCurrentAccessToken(null)
清除 Access Token,并通过clearAppCache
清除应用缓存。
5.3.5.3 注意事项
- 权限管理: 在请求用户信息时,需要确保请求的权限(如
email
,public_profile
)已获得用户授权。 - 错误处理: 处理可能的错误,如网络错误、权限被拒绝等。
- 安全性: 确保 Access Token 的安全,避免泄露。
5.4 总结
本章节介绍了 React Native 中的第三方登录功能,包括如何使用 react-native-google-signin
和 react-native-facebook-login
库来实现 Google 和 Facebook 登录,以及如何处理登录状态和用户信息。通过合理使用第三方登录,可以简化用户注册和登录流程,提高用户体验。
课后作业
- 实现一个包含 Google 和 Facebook 登录功能的应用。
- 获取并显示用户信息,如用户姓名和邮箱。
- 实现登出功能,清除用户登录状态。
- 阅读
react-native-google-signin
和react-native-facebook-login
官方文档,深入了解其他高级功能和最佳实践。
作者简介
前腾讯电子签的前端负责人,现 whentimes tech CTO,专注于前端技术的大咖一枚!一路走来,从小屏到大屏,从 Web 到移动,什么前端难题都见过。热衷于用技术打磨产品,带领团队把复杂的事情做到极简,体验做到极致。喜欢探索新技术,也爱分享一些实战经验,帮助大家少走弯路!
温馨提示:可搜老码小张公号联系导师