模块 3:添加身份验证
在此模块中,您将使用 Amplify CLI 和库配置和添加身份验证到您的应用程序中。
简介
您将添加的下一个功能是用户身份验证。在此模块中,您将了解如何使用 Amplify CLI 和库对用户进行身份验证,以利用托管用户身份提供商 Amazon Cognito。
您还将了解如何使用 Cognito 托管用户界面展示整个用户身份验证流,从而使用户只需几行代码即可注册、登录和重置密码。
使用“托管用户界面”意味着应用程序利用 Cognito 网页登录和注册用户界面流。应用程序的用户将重定向到 Cognito 托管的网页,并在登录后重定向回应用程序。当然,Cognito 和 Amplify 也支持本机 UI,您可以按照这些研讨会说明了解有关自定义身份验证 UI 的更多信息。
您将学到的内容
- 创建和部署身份验证服务
- 配置 Android 应用程序以包含 Cognito 托管的 UI 身份验证
重要概念
Amplify 库 – 您可以使用 Amplify 库从 Web 应用程序或移动应用程序中与 AWS 服务互动。
身份验证 – 在软件中,身份验证是使用身份验证服务或 API 验证和管理用户身份的过程。
时长
10 分钟
使用的服务
实施
-
创建身份验证服务
要创建身份验证服务,请打开一个终端,然后执行以下命令:
amplify add auth ? Do you want to use the default authentication and security configuration? Select Default configuration with Social Provider and press enter ? How do you want users to be able to sign in? Select the default Username and press enter ? Do you want to configure advanced settings? Select the default No, I am done and press enter ? What domain name prefix do you want to use? Select the default and press enter Enter your redirect signin URI: type gettingstarted:// and press enter ? Do you want to add another redirect signin URI? Select the default N and press enter Enter your redirect signout URI: type gettingstarted:// and press enter ? Do you want to add another redirect signout URI? Select the default N and press enter ? Select the social providers you want to configure for your user pool: do not select any provider and press enter
当您看到此消息时,即表示配置成功(资源的确切名称将有所不同):
Successfully added resource androidgettingstartedfc5a4717 locally
-
部署身份验证服务
现在,已在本地配置身份验证服务,我们可以将它部署到云:在终端中,请在项目目录中执行以下命令:
amplify push # press Y when asked to continue
片刻之后,您应看到以下消息:
✔ All resources are updated in the cloud Hosted UI Endpoint: https://androidgettingstarted-dev.auth.eu-central-1.amazoncognito.com/ Test Your Hosted UI Endpoint: https://androidgettingstarted-dev.auth.eu-central-1.amazoncognito.com/login?response_type=code&client_id=1234567890&redirect_uri=gettingstarted://
-
向项目添加 Amplify 身份验证库
在转到代码之前,请先返回 Android Studio,将以下依赖项连同您之前添加的其他 `amplifyframework` 实现一起,添加到您的模块的 `build.gradle`,然后在看到提示时,单击 Sync Now:
dependencies { ... // Amplify core dependency implementation 'com.amplifyframework:core:1.4.0' implementation 'com.amplifyframework:aws-auth-cognito:1.4.0' }
-
在运行时配置 Amplify 身份验证库
返回 Android Studio,打开 Backend.kt 文件。在后端类中,向我们在上一部分(在 initialize() 方法中)添加的 Amplify 初始化代码添加一行。
完整代码块应如下所示:
// inside Backend class fun initialize(applicationContext: Context) : Backend { try { Amplify.addPlugin(AWSCognitoAuthPlugin()) Amplify.configure(applicationContext) Log.i(TAG, "Initialized Amplify") } catch (e: AmplifyException) { Log.e(TAG, "Could not initialize Amplify", e) } return this }
请不要忘记添加导入语句,Android Studio 会自动为您完成此操作(在 Mac 上,在代码编辑器检测到的每个错误上,同时按 Alt 和 Enter 键)。
像在上一步骤中那样,为每个缺少的类定义添加所需的导入语句(在红色单词上同时按 Alt 和 Enter 键)。
要验证一切是否都按预期运行,请构建项目。单击 Build 菜单,并选择 Make Project,或者,在 Mac 上按 ⌘F9。应该不会出现错误。
-
在运行时触发身份验证
其余代码更改会跟踪用户的状态(他们是否已登录?)并在用户单击锁定图标时触发“SignIn/SignUp”用户界面。
a.添加 signIn 和 signOut 方法在后端类中的任意位置,添加以下四种方法:private fun updateUserData(withSignedInStatus : Boolean) { UserData.setSignedIn(withSignedInStatus) } fun signOut() { Log.i(TAG, "Initiate Signout Sequence") Amplify.Auth.signOut( { Log.i(TAG, "Signed out!") }, { error -> Log.e(TAG, error.toString()) } ) } fun signIn(callingActivity: Activity) { Log.i(TAG, "Initiate Signin Sequence") Amplify.Auth.signInWithWebUI( callingActivity, { result: AuthSignInResult -> Log.i(TAG, result.toString()) }, { error: AuthException -> Log.e(TAG, error.toString()) } ) }
然后为每个缺少的类定义添加所需的导入语句(在红色单词上按 Alt 和 Enter 键)。当您可以在多个类之间进行选择时,请务必从 Amplify 包中选择一个,如下面的屏幕截图所示。
请注意,我们没有在这些方法中更新 UserData.isSignedIn 标记,该操作将在下一节中完成。
b.添加身份验证中心侦听器
为了跟踪身份验证状态的变化,我们添加了代码以订阅由 Amplify 发送的身份验证事件。我们在 Backend.initialize() 方法中初始化该中心。
在收到身份验证事件时,我们将调用 updateUserData() 方法。此方法可使 UserData 对象保持同步。UserData.isSignedIn 属性是 LiveData<Boolean>,这意味着当值更改时,订阅此属性的观察者将收到通知。我们使用此机制来自动刷新用户界面。您可以在 Android 文档中了解关于 LiveData 的更多信息。
我们还添加了代码以在应用程序启动时检查以前的身份验证状态。当应用程序启动时,它会检查 Cognito 会话是否已存在,并相应地更新 UserData。
在 Backend.initialize() 中,在 try/catch 块之后和 return 语句之前添加以下代码。
// in Backend.initialize() function, after the try/catch block but before the return statement Log.i(TAG, "registering hub event") // listen to auth event Amplify.Hub.subscribe(HubChannel.AUTH) { hubEvent: HubEvent<*> -> when (hubEvent.name) { InitializationStatus.SUCCEEDED.toString() -> { Log.i(TAG, "Amplify successfully initialized") } InitializationStatus.FAILED.toString() -> { Log.i(TAG, "Amplify initialization failed") } else -> { when (AuthChannelEventName.valueOf(hubEvent.name)) { AuthChannelEventName.SIGNED_IN -> { updateUserData(true) Log.i(TAG, "HUB : SIGNED_IN") } AuthChannelEventName.SIGNED_OUT -> { updateUserData(false) Log.i(TAG, "HUB : SIGNED_OUT") } else -> Log.i(TAG, """HUB EVENT:${hubEvent.name}""") } } } } Log.i(TAG, "retrieving session status") // is user already authenticated (from a previous execution) ? Amplify.Auth.fetchAuthSession( { result -> Log.i(TAG, result.toString()) val cognitoAuthSession = result as AWSCognitoAuthSession // update UI this.updateUserData(cognitoAuthSession.isSignedIn) when (cognitoAuthSession.identityId.type) { AuthSessionResult.Type.SUCCESS -> Log.i(TAG, "IdentityId: " + cognitoAuthSession.identityId.value) AuthSessionResult.Type.FAILURE -> Log.i(TAG, "IdentityId not present because: " + cognitoAuthSession.identityId.error.toString()) } }, { error -> Log.i(TAG, error.toString()) } )
要验证一切是否都按预期运行,请构建项目。单击 Build菜单,并选择 Make Project,或者,在 Mac 上按 ⌘F9。应该不会出现错误。
c.更新用户界面代码
代码中的最后一个更改与用户界面相关,我们将 FloatingActionButton 添加到主要活动中。
在“res/layout”下,打开 activity_main.xml,并将现有的 FloatingActionButton 替换为以下内容:
<com.google.android.material.floatingactionbutton.FloatingActionButton android:id="@+id/fabAuth" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_gravity="bottom|end" android:layout_margin="@dimen/fab_margin" android:src="@drawable/ic_baseline_lock" app:fabCustomSize="60dp" app:fabSize="auto" />
在“res/drawable”下添加一个锁状图标。右键单击“drawable”,选择 New,然后选择 Vector Asset。从 Clilp Art 中选择锁状图标,然后输入 ic_baseline_lock(不含 _24)作为名称,并从 Clip Art 中选择闭合的锁状图标。单击 Next,然后单击 Finish。
对打开的锁状图标重复相同的操作。
执行完以上操作后,您的“drawable”目录下应具有以下文件:
现在,在代码中链接新创建的按钮。在 java/com.example.androidgettingstarted/ 下,打开 MainActivity.kt 并添加以下代码。
// anywhere in the MainActivity class private fun setupAuthButton(userData: UserData) { // register a click listener fabAuth.setOnClickListener { view -> val authButton = view as FloatingActionButton if (userData.isSignedIn.value!!) { authButton.setImageResource(R.drawable.ic_baseline_lock_open) Backend.signOut() } else { authButton.setImageResource(R.drawable.ic_baseline_lock_open) Backend.signIn(this) } } }
还是在 MainActivity 中,在 onCreate() 方法的末尾添加以下代码:
setupAuthButton(UserData) UserData.isSignedIn.observe(this, Observer<Boolean> { isSignedUp -> // update UI Log.i(TAG, "isSignedIn changed : $isSignedUp") if (isSignedUp) { fabAuth.setImageResource(R.drawable.ic_baseline_lock_open) } else { fabAuth.setImageResource(R.drawable.ic_baseline_lock) } })
以上代码会针对 Userdata.isSignedIn 值注册观察者。当 isSignedIn 值更改时调用闭包。现在,我们只是更改锁状图标:当用户通过身份验证时为打开的锁,当用户没有会话时为闭合的锁。
要验证一切是否都按预期运行,请构建项目。单击 Build 菜单,并选择 Make Project,或者,在 Mac 上按 ⌘F9。应该不会出现错误。
d.更新 AndroidManifest.xml 和 MainActivity
最后,我们必须确保在 Cognito 托管用户界面提供的 Web 身份验证序列结束时启动我们的应用程序。我们在清单文件中添加一个新的活动。当接收到 gettingstarted URI 方案时,将调用该活动。
在 Android Studio 中的“manifests”下,打开 AndroidManifest.xml,并在应用程序元素中添加以下活动。
<activity android:name="com.amazonaws.mobileconnectors.cognitoauth.activities.CustomTabsRedirectActivity"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="gettingstarted" /> </intent-filter> </activity>
在 java/com.example.androidgettingstarted/ 下,打开 MainActivity.kt 并在类中的任意位置添加以下代码。
// MainActivity.kt // receive the web redirect after authentication override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) Backend.handleWebUISignInResponse(requestCode, resultCode, data) }
在 java/com.example.androidgettingstarted/ 下,打开 Backend.kt 并在类中的任意位置添加以下代码。
// Backend.kt // pass the data from web redirect to Amplify libs fun handleWebUISignInResponse(requestCode: Int, resultCode: Int, data: Intent?) { Log.d(TAG, "received requestCode : $requestCode and resultCode : $resultCode") if (requestCode == AWSCognitoAuthPlugin.WEB_UI_SIGN_IN_ACTIVITY_CODE) { Amplify.Auth.handleWebUISignInResponse(data) } }
e.构建和测试
要验证一切是否都按预期运行,请构建并运行项目。单击工具栏中的运行图标 ▶️,或按 ^ R。应该不会出现错误。应用程序将启动,且屏幕右下角会显示一个闭合的锁状浮动按钮。
以下是完整的注册流程。
结论
您现在已使用几行代码将用户身份验证添加到您的应用程序中! 在下一个模块中,我们将添加 API 到您的应用程序中。
添加 GraphQL API 和数据库