使用 Amplify 框架进行用户身份验证的完整 React Native 指南
在我之前的文章《使用 Amplify 框架进行用户身份验证的完整指南》中,我介绍了如何添加基于用户名/密码的身份验证以及与 Facebook、Google 或 Amazon 的 OAuth。
在本教程中,我将介绍如何使用 React Native 和 AWS Amplify 进行移动身份验证。本指南将涵盖 React Native 和 Expo。我将介绍如何实现以下用例:
- Google 和 Facebook 的 OAuth
- 与 Apple 的 OAuth
- 托管 UI(Google + Apple + Facebook + 用户名和密码在一个 UI 中)
- 用户名和密码验证
- 受保护的路线
- 监听身份验证事件
- 使用
withAuthenticator
HOC进行基本身份验证
入门
AWS Amplify 为想要创建具有实际生产就绪用户身份验证的应用程序的开发人员提供身份验证 API 和构建块。
使用 Amplify,您可以通过 OIDC 将基于用户名/密码的身份验证以及 OAuth 与 Facebook、Google、Amazon 或任何第三方 OAuth 提供商(例如 Auth0 或 Okta)结合起来。
我们还提供预先构建的“托管 UI”,通过单个函数调用提供完整的 OAuth + 用户名/密码流。
Amazon Cognito 简介
Amplify 框架使用Amazon Cognito作为主要的身份验证提供程序。Amazon Cognito User 是一项托管用户目录服务,可处理用户注册、身份验证、账户恢复及其他操作。
Amplify 与 Cognito 接口来存储用户数据,包括与 Facebook 和 Google 等其他 OpenID 提供商联合。
Amplify CLI 自动执行这些 AWS 资源的访问控制策略,并通过 GraphQL 提供细粒度的访问控制以保护 API 中的数据。
大多数现代应用程序都需要多种身份验证选项,例如 Facebook 登录 + 用户名/密码登录。Amazon Cognito 允许您使用单个用户注册表跨多种身份验证类型对用户进行身份验证,从而简化了此过程。
在本文中,您将学习如何使用 OAuth 以及用户名和密码登录向您的应用程序添加身份验证。
与 Apple、Google 和 Facebook 的 OAuth
安装 Amplify CLI
要使用 Amplify 在您的应用程序中构建身份验证,首先需要安装 AWS Amplify CLI。Amplify CLI 是一个命令行工具,可让您创建和部署各种 AWS 服务。
要安装 CLI,我们将运行以下命令:
$ npm install -g @aws-amplify/cli
接下来,我们将使用来自 AWS 账户的用户配置 CLI:
$ amplify configure
要观看 CLI 配置过程的视频演示,请单击此处。
创建 React Native 项目
接下来,我们将创建要使用的 React Native 应用程序。
如果使用 Expo
$ npx expo init rnamplify
> Choose a template: blank
$ cd rnamplify
$ npm install aws-amplify aws-amplify-react-native
如果使用 React Native CLI
$ npx react-native init rnamplify
$ cd rnamplify
$ npm install aws-amplify aws-amplify-react-native amazon-cognito-identity-js
$ cd ios
$ pod install --repo-update
$ cd ..
创建 Amplify 项目
现在我们可以从 React Native 应用程序的根目录中初始化一个新的 Amplify 项目:
$ amplify init
这里我们将指导您完成一系列步骤:
- 输入项目名称:amplifyauth(或您喜欢的项目名称)
- 输入环境名称:local(或您喜欢的环境名称)
- 选择您的默认编辑器:Visual Studio Code(或您的文本编辑器)
- 选择您正在构建的应用程序类型:javascript
- 您正在使用什么 JavaScript 框架:react-native
- 源目录路径:/
- 分发目录路径:build
- 构建命令:npm run-script build
- 启动命令:npm run-script start
- 您想使用 AWS 配置文件吗?是
- 请选择您要使用的配置文件:YOUR_USER_PROFILE
现在,我们的 Amplify 项目已经创建,我们可以继续下一步。
创建我们的 App ID
在我们的应用中,我们将有四种类型的身份验证:
- Facebook(OAuth)
- 谷歌(OAuth)
- 苹果 (OAuth)
- Cognito(用户名+密码)
接下来,我们需要创建 Apple、Facebook 和 Google 应用,以便为每个应用获取 App ID 和 App Secret。对于您想要启用的每个提供商,请按照以下说明创建 App ID。
要查看Facebook设置说明,请单击此处。
要查看Apple设置的说明,请参阅此处的教程。您只需创建App ID、Services ID和Private Key,无需创建 Client Secret。Services ID 的 Web 域名和 Return URL 暂时留空。
创建 Apple、Facebook 和 Google OAuth 凭证后,继续下一步。
创建和配置身份验证服务
现在我们的 Amplify 项目已经初始化,并且我们拥有来自 Apple、Facebook 和 Google 的 App ID 和机密,我们可以添加身份验证服务。
截至本文发布时,Amplify CLI 尚未添加对 Apple 的支持,因此我们需要另行一步,在仪表板中直接启用 Apple。目前,我们仅通过 CLI 启用 Google 和 Facebook。
要添加身份验证服务,我们可以运行以下命令:
$ amplify add auth
# If you already have a project configured & want to now add Social login, run amplify update auth instead
这将引导您完成一系列步骤:
- 是否要使用默认身份验证和安全配置?使用社交提供程序(联合身份验证)的默认配置
- 您希望用户在使用 Cognito 用户池时如何登录?用户名
- 注册需要哪些属性?电子邮件
- 您希望我们为您创建什么域名前缀?amplifyauthXXXXXXXXX(使用默认或创建自定义前缀)
- 输入您的重定向登录 URI:如果您使用的是 Expo:exp://127.0.0.1:19000/--/,如果您使用的是 React Native CLI:myapp://(这可以稍后更新以用于生产环境)
- 是否要添加另一个重定向登录 URI:N
- 输入您的重定向登出 URI:如果您使用的是 Expo:exp://127.0.0.1:19000/--/,如果您使用的是 React Native CLI:myapp://
- 是否要添加另一个重定向登出 URI:N
- 选择您想要为用户池配置的社交提供商:选择Facebook和Google
在上一步中,我们选择了默认配置和社交提供商(联合身份验证)。这将允许使用用户名/密码组合登录和 OAuth。如果您只需要用户名/密码,则可以选择默认配置或手动配置。
我们还设置了redirect
URI。这很重要,稍后我们将使用此 URI 更新 Expo、Xcode 和 Android Studio 项目。
最后,系统将提示您输入 Facebook 和 Google 的应用程序 ID 和机密,输入它们并按 Enter 继续。
现在身份验证服务已成功配置,我们可以通过运行以下命令来部署该服务:
$ amplify push
运行后,amplify push
您应该会看到一条成功消息,并且OAuth 端点也应该被注销到控制台:
OAuth 端点看起来应该像这样:
https://amplifyauth8e79c995-8e79c995-local.auth.eu-central-1.amazoncognito.com/
如果您在->键下的任何时候需要此 OAuth 端点,也可以在src/aws-exports.js中引用它。oauth
domain
您将需要使用此端点来完成 Apple、Facebook 和 Google OAuth 提供商的配置。
配置 Facebook
接下来,打开我们之前创建的 Facebook 应用程序并单击左侧菜单中的“基本” 。
滚动到书籍并单击“添加平台”,然后选择网站:
对于 _Site URL),输入/oauth2/idpresponse
附加到 Site URL 的 OAuth Endpoint URL:
保存更改。
接下来,在 App Domains 中输入您的 OAuth Endpoint:
保存更改。
接下来,从导航栏中选择“产品”,然后从“Facebook 登录”中进行设置并选择“Web”。
对于有效的 OAuth 重定向 URI,请使用 OAuth 端点 + /oauth2/idpresponse
。如果系统提示您输入站点 URL,也请使用此端点(例如https://amplifyauth8e79c995-8e79c995-local.auth.eu-central-1.amazoncognito.com/oauth2/idpresponse):
保存更改。
单击页面顶部的“开启”开关,确保您的应用处于上线状态。
配置Google
现在 Facebook 已经配置完毕,我们可以配置 Google 了。首先,我们需要进入Google 开发者控制台并更新 OAuth 客户端。
单击客户端 ID 来更新设置。
在授权的 JavaScript 来源下,添加 OAuth 端点。
对于授权重定向 URI,将 OAuth 端点添加/oauth2/idpresponse
到 URL 中:
保存更改。
配置 Apple
打开Apple 开发者控制台,单击左侧菜单中的“证书、ID 和配置文件” ,然后单击“标识符”。
在应用程序 ID下拉菜单中,选择服务 ID。
单击您之前创建的服务 ID,然后单击“使用 Apple 登录”旁边的“配置”。
在此处输入“域”和“返回 URL”。“域”应为aws-exports.jsoauth
文件中的域值。“返回 URL”将是 的变体,如下所示:domain
https://<domain>/oauth2/idpresponse
因此,您的返回 URL 可能类似于:
https://rnauth6508c5d5-6508c5d5-dev.auth.us-east-1.amazoncognito.com/oauth2/idpresponse
注意:您不必验证域,因为只有 Amazon Cognito 不使用的交易方法才需要验证。
将 Apple 登录添加到 Cognito 服务
Amplify CLI 将 Google 和 Facebook OAuth 服务与 Amazon Cognito 集成,但要启用“使用 Apple 登录”,我们必须进入控制台并手动操作,直到 Amplify CLI 添加此功能。要打开 Cognito 项目,请运行以下命令:
$ amplify console auth
? Which console: User Pool
在左侧菜单中,选择“身份提供者”。在此部分中,单击“使用 Apple 登录”,输入 Apple 服务 ID、团队 ID、密钥 ID,然后上传 Apple 开发者控制台提供给您的私钥。
接下来,点击应用程序客户端设置并为每个应用程序客户端启用使用 Apple 登录。
最后,单击属性映射并确保启用电子邮件并将其映射到电子邮件。
配置本地重定向 URI
在 amplify 配置步骤中,我们设置了重定向 URI,以便在用户身份验证后重新打开应用。现在,我们需要在移动项目中启用这些重定向 URI。这些步骤会根据您使用 Expo 还是 React Native CLI 进行构建而有所不同。
博览会 - 重定向 URI
如果您使用 expo,请打开app.json文件并将以下键值对添加到“expo”属性:
{
"expo": {
"scheme": "myapp",
// other values
}
}
React Native CLI - 重定向 URI
如果您使用 React Native CLI 并使用本机项目,则需要配置 Xcode 项目和 Android Studio 项目。
iOS - Xcode 配置
对于 iOS,打开 Xcode 项目(在ios文件夹中,rnamplify.xcworkspace)。在这里,info.plist
以源代码形式打开,并添加以下内容:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>myapp</string>
</array>
<dict>
</array>
如需查看完整示例,请单击此处。
Android - Android Studio 配置
在 Android Studio 中,打开android/app/main/AndroidManifest.xml。在此文件中,添加以下intent-filter:
<intent-filter android:label="filter_react_native">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="myapp" />
</intent-filter>
如需查看完整示例,请单击此处。
尝试一下
现在,项目和服务已配置完毕,我们可以开始编写一些 JavaScript。
我们需要做的第一件事是配置 React Native 项目以使用 Amplify 凭证。为此,打开index.js并添加以下代码:
import Amplify from 'aws-amplify'
import config from './aws-exports'
Amplify.configure(config)
现在,我们可以测试身份验证 API。为此,我们将使用这些Auth.federatedSignIn
方法。这些方法允许我们启动与单个提供商的联合登录,或启动用于与任何提供商登录的托管 UI。
// import the Auth class
import { Auth } from 'aws-amplify'
<Button
title="Sign in with Google"
onPress={() => Auth.federatedSignIn({ provider: "Google" })}
/>
<Button
title="Sign in with Facebook"
onPress={() => Auth.federatedSignIn({ provider: "Facebook" })}
/>
<Button
title="Sign in with Apple"
onPress={() => Auth.federatedSignIn({ provider: "SignInWithApple" })}
/>
<Button
title="Launch Hosted UI"
onPress={() => Auth.federatedSignIn()}
/>
接下来,运行应用程序来测试一切:
# If using Expo
$ expo start
# If not using Expo
$ npx react-native run-ios
# or
$ npx react-native run-android
登录后,我们可以测试其他一些东西。
要注销当前用户的凭据:
const user = await Auth.currentAuthenticatedUser().catch(err => console.log(err))
使用上述方法,我们还可以随时检查当前用户是否已登录。如果未登录,则会显示错误消息,告知我们用户未登录。
如果他们已登录,则该user
对象将填充已登录用户的所有元数据。
要退出当前用户:
await Auth.signOut()
用户名+密码认证
通过我们当前的设置,我们还可以使用用户名和密码注册和注销用户。
为此,我们需要将他们的信息捕获到表单中。使用该类Auth
,我们可以处理许多不同的场景,包括但不限于:
- 注册
- 确认注册(MFA)
- 登录
- 确认登录 (MFA)
- 重置密码
让我们看一下如何注册用户。这是一个非常基础的示例,没有考虑在注册、登录以及确认注册或登录之间切换表单状态。下面是更详细的示例链接。
// import the Auth component
import { Auth } from 'aws-amplify'
// store the form state
state = {
username: '', email: '', password: ''
}
// sign the user up
async signUp = () => {
const { username, email, password } = this.state
await Auth.signUp({ username, password, attributes: { email }})
console.log('user successfully signed up')
}
要查看该类的所有可用方法,请查看此处的Auth
文档。
如果您对如何创建自定义身份验证流程感兴趣,请查看此示例中的组件,或者直接查看此处的整个 React Native 身份验证启动器。
受保护/私人路线
创建自定义身份验证流程时,您需要处理的一件事是受保护或私有路由。
受保护的路由是指您不希望某些用户访问的路由或视图。在我们的示例中,我们将实现受保护的路由,以重定向未登录的用户,并允许已登录的用户继续访问。
我将展示的示例假设您正在使用 React Navigation,但如果您使用不同的导航库,其想法仍然相同。
本质上,您需要做的是有一个路线更改的监听器,或者如果您使用 React Navigation,则可以使用 prop 直接挂钩到路线更改onNavigationStateChange
。
在这个函数中,我们可以获取用户的凭证并检查用户是否已登录。如果他们已登录,我们允许他们继续下一个路线。
如果他们尚未登录,我们会将他们重定向到身份验证屏幕:
import React from 'react'
import { createSwitchNavigator, createAppContainer, NavigationActions } from 'react-navigation'
import Auth from './nav/auth/Auth'
import MainNav from './nav/main/MainNav'
import { Auth as AmplifyAuth } from 'aws-amplify'
const SwitchNav = createSwitchNavigator({
Auth: {
screen: Auth
},
MainNav: {
screen: MainNav
}
})
const Nav = createAppContainer(SwitchNav)
class App extends React.Component {
checkAuth = async () => {
try {
await AmplifyAuth.currentAuthenticatedUser()
} catch (err) {
this.navigator.dispatch(
NavigationActions.navigate({ routeName: 'Auth' })
)
}
}
render() {
return (
<Nav
ref={nav => this.navigator = nav}
onNavigationStateChange={this.checkAuth}
/>
)
}
}
export default App
如需完整实现,请查看此处的示例项目。
监听身份验证事件
我们可以初始化一个监听器,它将监听我们的身份验证状态的变化,并允许我们访问发生的身份验证事件类型并根据该数据更新应用程序状态。
使用 AmplifyHub
模块,我们可以非常轻松地做到这一点:
import { Hub } from 'aws-amplify';
Hub.listen('auth', (data) => {
const { payload } = data;
console.log('A new auth event has happened: ', data.payload.data.username + ' has ' + data.payload.event);
})
使用withAuthenticator
HOC进行基本身份验证
如果您只是想使用基本的用户名 + 密码验证来启动和运行,那么您可以使用withAuthenticator
HOC。
该组件只需几行代码即可将身份验证置于应用程序中的任何组件之前:
import { withAuthenticator } from "aws-amplify-react-native";
class App extends React.Component { /* your code /* }
export default withAuthenticator(App)