如果你是一名iOS开发者,对SwiftUI和Auth0的身份验证感到陌生,那么你就有机会了。在本教程中,你将在SwiftUI中构建一个应用程序,使用Auth0实现基本的登录和注销
本教程包括使用Auth0.swift SDK的2.0.0版本,在使用Swift编程语言和SwiftUI框架编写的iOS应用中实现登录/注销。在这个过程中,你将快速了解我们新修订的Swift SDK的基础知识,以及如何将其与苹果的SwiftUI框架一起使用。你还将熟悉Auth0仪表板,并学习如何使用它来注册应用程序和管理用户。
如果你想在关注构建和执行步骤的同时略过这些内容,请寻找🛠表情符号。
苹果的SwiftUI框架
SwiftUI是一个用户界面工具包,也是苹果在2019年推出的构建应用程序的 "新方法"。通过SwiftUI,你可以使用Swift代码以声明的方式构建用户界面,这意味着你可以指定用户界面在不同的状态下应该如何看和表现。你不必指定用户界面如何在这些状态之间移动--它为你解决了这个问题。如果你知道React编程,你会发现SwiftUI很熟悉。
SwiftUI的方法与UIKit使用的方法完全不同,UIKit是iOS最初的UI工具箱,可以追溯到2007年。在UIKit中,你使用Interface Builder构建用户界面,这是一个拖放式布局工具,以图形方式构建应用程序的视图。你使用outlet和动作将UI元素与应用程序的视图控制器中的变量和方法连接起来。UIKit使用命令式方法,这意味着你要定义程序如何在各状态之间移动,以及UI在这些状态下的外观和行为。
Auth0和Auth0.swiftSDK
在应用程序中添加登录和注销似乎是一项简单的任务--直到你尝试。你必须处理多种登录方式,确认电子邮件地址和密码,管理用户,并处理安全性和可扩展性。每一个问题都有几十种考虑因素、风险、问题和边缘案例。
Auth0解决了这个问题。有了Auth0和几行代码,你的应用程序可以拥有一个全功能的系统,支持用用户名/密码组合登录、单点登录和社交账户、无密码登录、生物识别等。你也不必处理 "幕后 "的问题!相反,你可以专注于你的应用程序的主要功能。
Auth0.swift是所有苹果平台的Auth0 SDK:不仅是iOS,还有macOS、iPadOS、watchOS和tvOS。它是我们使用最多的第三个SDK,占到我们系统所有API请求的11%。如果你正在建立一个需要验证或授权其用户的苹果设备应用程序,你需要这个SDK!
Auth0.swift的最新版本,即2.0.0版,包含了我们在过去五年中从苹果设备上的应用安全中所获得的经验。如果你使用过早期版本,你会喜欢它更新的错误处理、对async/await和Combine的支持、改进的默认配置、新的文档,以及我们删除了过时的方法和遗留功能。如果你是Auth0的新手,你会惊喜地发现,你只需要写很少的代码就可以在你的应用程序中添加认证。
你将建立什么
在本教程中,你将构建一个简单的、单屏幕的iOS应用,允许用户使用Auth0登录和注销。在登录时,屏幕将有不同的外观,并显示用户的姓名、电子邮件地址和他们个人资料中的照片。
你将从Xcode的菜单栏中选择文件→新→项目......,而不是从一个启动项目中建立这个应用程序,你将从头开始建立它。
快速浏览该应用程序
当你启动完成的应用程序时,你会看到一个标志图标,一些状态文本,应用程序的标题,和一个登录按钮。
登录按钮将用户带到Auth0通用登录界面,该界面出现在一个自定义的浏览器窗口中。
当你使用Auth0为你的应用程序添加登录/注销功能时,你将认证委托给Auth0的通用登录,这是一个跨平台的基于webview的页面,支持登录、注册账户和其他认证流程。在这个练习中,你将使用默认的登录页面的 "外观和感觉",但你可以定制它以符合你的应用程序或组织的品牌。
如果用户成功登录,"通用登录 "屏幕和它的浏览器窗口就会消失,用户就会回到应用中,这时会显示用户资料中的选定信息,即他们的资料照片、姓名和电子邮件地址,以及一个注销按钮。
注销按钮将用户注销并返回到初始屏幕。
先决条件
以下是这个练习所需的软件、硬件和知识的清单。
一个Auth0账户
你将为本文的练习编写的应用程序使用Auth0来提供登录和注销功能。作为它的开发者,你需要一个Auth0账户。你可以注册一个免费账户,它允许你为多达10个应用程序和7000个用户添加认证。这对于评估该平台,以及原型设计、开发和测试来说,应该是足够了。
一个iOS开发设置
要为任何苹果硬件开发应用程序,你需要一台运行苹果集成开发环境Xcode的Mac电脑。
- 2013年中期或以后的大多数Mac,至少有8GB内存(16GB为佳)。
- 一个较新的macOS版本,最好是Big Sur或Monterey。
- Xcode11.0版(2019年9月)或更高版本。写这篇文章时,我使用了当前的版本:13.2.1(13C100)版本,于2021年12月17日发布。
一个iOS设备,虚拟或真实的
Xcode自带的模拟器是一个应用程序,可以创建虚拟设备,模拟iPhone、iPad和iPod Touch的最新型号,这些设备都运行iOS 15。
要为模拟器安装早期版本的iOS,从Xcode菜单中选择Preferences...,然后选择Components标签。你会看到一个旧版本的列表,不仅仅是iOS,还有watchOS和tvOS。
使用模拟器的好处之一是,你不需要一个苹果开发者账户--免费或付费--来使用它。
虽然模拟器很方便,但它不能替代实际的物理设备。它提供了更真实的测试体验,因为你不能在模拟器上做某些事情,如运动/倾斜感应和增强现实。
要将应用程序直接部署到设备上进行测试,你需要一个免费的苹果开发者账户,这又需要一个苹果ID。如果你没有Apple ID,请在这里注册一个。一旦你有了Apple ID,去developer.apple.com,点击页面顶部的 帐户在页面的顶部,然后登录。
你需要在你的开发者账户中注册设备,以便向其部署应用程序;你可以在苹果开发者网站的这个页面上这样做。每个会员年度你最多可以注册100台设备。你需要提供设备的UDID(唯一设备标识符),你可能会发现这个网站很有帮助。一旦你注册了一个设备,你就可以直接向其部署应用程序;见 将你的应用程序分发到注册设备上获取更多信息。
要将应用程序部署到App Store,你需要一个付费账户。欲了解更多详情,请参阅苹果开发者注册页面。
要了解更多关于在虚拟和真实的iOS设备上运行应用程序的信息,请从苹果的文章开始。 在模拟器或设备上运行你的应用程序.
对Swift和struct
s有一定了解
虽然不是完全必要,但如果你熟悉Swift编程语言和iOS开发,会有所帮助。如果这些对你来说是新的,Swift编程语言,或UIKit框架,请尝试这个苹果教程。 今天就开始吧。.
SwiftUI在很大程度上依赖于struct
,所以你可能会发现复习一下它们的基础知识很有帮助。你可能会发现Hacking with Swift 的文章。 如何创建你自己的结构的文章有帮助。
制作一个新的SwiftUI应用程序
让我们从构建一个新的SwiftUI应用开始。一旦我们有了一个基本的应用程序,并且你已经了解了一些SwiftUI界面元素,我们将纳入Auth0认证,然后通过添加一些用户体验的亮点来完成练习。
从头开始
🛠 启动Xcode,通过打开文件菜单并选择新建→项目....,创建一个新项目。
Xcode将显示这个对话框,在这里你将为你要创建的应用程序选择一个项目模板。每个模板都会为不同的应用程序生成必要的文件,包括通用应用程序、视频游戏、增强现实应用程序以及为iMessage和Safari添加自定义功能的附加组件。
🛠在这个练习中,我们想为iOS创建一个通用的应用程序,所以选择iOS标签,然后选择App项目模板,它将在集合的左上角。点击 "下一步"按钮来确认选择。
Xcode将显示下一个对话框,在这里你将给项目起一个对人类和计算机友好的名字,并指定你将使用哪种编程语言和框架。
🛠 在这个对话框中,做以下工作
- 在 "产品名称 "栏中输入项目的名称。在这个练习中,我使用的名字是
SwiftUI Login Demo
。 - 从团队菜单中选择一个团队。如果你还没有创建一个开发团队,并且想继续这个练习,而不经过注册苹果开发者账户和创建团队的过程,请选择无。这将让你把应用程序部署到模拟器上,但不是部署到设备上。
- 输入
com.example
到组织标识符字段中。 - 从界面菜单中选择SwiftUI。
- 从语言菜单中选择Swift。
- 点击 "下一步"按钮。
🛠 Xcode将显示另外一个对话框--这个对话框让你指定你的项目及其文件的存储位置。选择一个位置。
一旦你完成了上面的步骤,Xcode将为你的项目生成文件并显示主窗口。
每当你使用App模板创建一个新的SwiftUI项目时,Xcode会生成一个名为ContentView
的单一视图,其内容是你在创建项目后看到的第一件事。
这是ContentView
'的初始代码,上面有编号的注解。
import SwiftUI // 1
// 2
struct ContentView: View {
// 3
var body: some View {
// 4
Text("Hello, world!")
.padding()
}
}
// 5
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
下面是上面编号注释所标注的代码中发生的事情。
- 任何定义了UI元素的SwiftUI项目文件,无论是整个屏幕还是单个控件,都必须导入SwiftUI库。
- 在 SwiftUI 中,每个 UI 元素都是一个视图--一个采用
View
协议的struct
,它定义了一个 SwiftUI 屏幕元素应该提供的功能。这个特殊的视图,ContentView
,定义了应用程序的单一屏幕。 View
协议有一个要求:任何采用该协议的类型必须有一个body
属性,该属性定义了 UI 元素的外观和行为。body
属性的类型是some View
,这是Swift 表示 "某个采用View
协议的类型"的方式。请注意,body
'的值是由闭包决定的,闭包是一个代码块,你可以传递给一个函数。- 你可能已经明白了,
Text
是一个在屏幕上显示文本的视图。视图后面可以有修改器--改变其外观或行为的方法。在这个例子中,我们用修改器在Text
视图的内容和边缘之间添加空间。padding()
修改器。 - 当Xcode为一个视图创建一个新文件时,它会生成两个
struct
:一个是出现在应用程序中的视图,一个是出现在Xcode编辑器中的预览。这个struct
,ContentView_Previews
,生成一个预览的ContentView
,让你看到它的样子,而不需要你编译和运行应用程序。
当编辑视图文件时,Xcode将其屏幕中央的编辑区域划分为两个区域:一个代码编辑器和一个预览浏览器。
🛠要看应用程序的用户界面是什么样子,从模拟器设备菜单中进行选择,然后点击预览查看器中的恢复按钮。
你应该看到像这样的东西。
🛠 你也可以选择通过运行该应用程序来看看它的运行情况。选择一个模拟器设备或将一个真实的设备连接到你的电脑,然后点击运行按钮。
模拟器将启动,你很快就会看到这个。
为应用程序添加状态和互动性
现在是时候让这个应用程序做更多的事情了,而不仅仅是显示 "你好,世界!"让我们创建该应用程序的两种状态--注销和登录--并为用户提供一种在它们之间导航的方法。
当启动时,该应用程序将具有标题文本和一个登录按钮。
点击 "登录"按钮,你会进入这个屏幕,上面有 "已登录 "的文字和 "注销"按钮。
🛠在Xcode中,打开ContentView
文件,用下面的内容替换ContentView
struct
。
struct ContentView: View {
// 1
@State private var isAuthenticated = false
var body: some View {
// 2
if isAuthenticated {
// 3
VStack {
Text("Logged in")
.padding()
// 4
Button("Log out") {
isAuthenticated = false
}
.padding()
}
} else {
// 5
VStack {
Text("SwiftUI Login Demo")
.padding()
// 6
Button("Log in") {
isAuthenticated = true
}
.padding()
}
} // if isAuthenticated
}
}
我在代码中标上了编号的注释,下面会有解释。
- 这一行声明了一个新的私有实例变量,
isAuthenticated
。它以@State
开始,这告诉了SwiftUI关于它的一些事情。@State
通知SwiftUI,该变量是视图状态的一部分,而视图状态是影响其外观和行为的变量集。当视图中任何状态变量的值发生变化时,SwiftUI会重新绘制视图以反映该变化。 的值将被设置为isAuthenticated
true
的值将被设置为:如果用户已登录,则为false
的值将被设置为用户已登录,而如果用户已注销。由于这个值会影响应用程序的外观,我把它变成了一个状态变量。@State
也允许 '的方法来改变它的值。默认情况下,一个 '的方法不能改变其变量的值。struct
struct
- 应用程序应根据
isAuthenticated
的值来显示不同的屏幕。if
语句决定了将被分配给body
的值,这决定了屏幕上的用户界面。 - 这是语句的一个分支
if
语句的分支,在用户登录的情况下执行。这个分支的结果必须是一个单一的视图,这是个问题:我们想显示两个视图:一些文本和注销按钮。为了解决这个限制,我们将使用一个视图作为其他视图的容器。VStack
,其名称是 "垂直堆栈 "的简称。它最多可以容纳10个视图,以垂直列的形式显示,第一个视图出现在顶部,后面的视图出现在最顶部的视图下面。 Button
视图需要两个参数。- 按钮的标签是一个字符串值。"Logged in"。
- 一个闭包,定义了当用户按下按钮时应该发生的事情:它把
isAuthenticated
的值改为false
.由于isAuthenticated
是一个状态变量,改变其值会导致SwiftUI重新绘制ContentView
。当这种情况发生时,应用程序将执行语句的另一个分支if
语句的另一个分支。
- 这是语句的分支
if
语句的分支,如果用户没有登录就会执行。这个分支的结果是另一个VStack
,这个分支包含应用程序的标题和登录按钮。 - 这个
Button
视图与登录按钮的视图类似,只是它写的是Log out,并在按下时将isAuthenticated
。true
当按下时。
🛠 如果 "恢复"按钮在预览窗格中是可见的,点击它。它将更新以显示新的用户界面。
🛠 运行该应用程序以查看其运行情况。点击登录和注销按钮,从一个屏幕到另一个屏幕。
重构按钮的代码
随着SwiftUI视图变得越来越复杂,其代码往往变得越来越难读。保持其可读性的一个方法是将闭包中的代码放到它们自己的方法中。
🛠 将此扩展添加到ContentView
,在ContentView
和ContentView_Previews
之间。
extension ContentView {
func login() {
isAuthenticated = true
}
func logout() {
isAuthenticated = false
}
}
🛠 将ContentView
中的注销按钮的代码更新为以下内容。
Button("Log out") {
logout()
}
.padding()
🛠 将ContentView
中登录按钮的代码更新为以下内容。
Button("Log in") {
login()
}
.padding()
🛠 运行该应用程序。它仍将以同样的方式工作,但通过将按钮的闭包提取到自己的方法中,并将这些方法放到自己的扩展中,代码将更容易阅读和修改。
设置应用程序以与Auth0集成
现在你已经了解了一些 SwiftUI 视图,也看到了 SwiftUI 是如何使用状态来配置用户界面的,现在是时候将应用程序改为使用 Auth0 进行用户认证的应用程序了。
安装Auth0.swift包
让我们来完成这项任务的第一部分:设置应用程序以与Auth0集成。我们将通过在项目中添加Auth0.swift包来实现这一目标。
Auth0.swift是一个库的集合,允许用Swift编写的应用程序利用Auth0的授权和认证功能。它包含这些Swift库。
Auth0
:一个用于使用Auth0的API的工具包,包括Authentication API,你将用它来实现应用程序中的登录和注销。JWTDecode
:一个用于解码JWTs(JSON网络令牌)的库。SimpleKeychain
:用于安全存储小块数据(如用户证书)的iOS Keychain的封装器。
有三种方法来安装Auth0.swift。
- Swift Package Manager,苹果的依赖管理器
- Cocoapods,一个历史悠久的第三方软件包管理器,最早发布于2011年,在许多项目中使用
- Carthage,另一个第三方软件包管理器
我选择在本教程中使用Swift Package Manager,因为它内置在Xcode中,不需要额外的软件。如果你愿意使用Cocoapods或Carthage来安装Auth0.swift,请看这些说明。
🛠 要开始安装Auth0.swift包的过程,打开文件菜单并选择添加包....会出现这个窗口。
🛠 在窗口的搜索栏中输入Auth0.swift包库的URL。
https://github.com/auth0/Auth0.swift.git
Xcode将在线搜索并显示它在该URL中找到的任何包。搜索应该产生一个单一的结果。Auth0.swift。
🛠 当Auth0.swift包出现在列表中时,选择它。在依赖关系规则菜单中,选择Up to Next Major Version,并确保其右边的文本字段中的版本号是os 2.0.0
,然后点击添加包。
🛠 你会被要求确认你想添加Auth0.swift包。点击 "添加软件包"来向Xcode保证,是的,你想要Auth0.swift。
当Auth0.swift完成安装后,它的包将出现在项目屏幕的Package Dependencies标签下的列表中。你会看到Auth0.swift的库列在项目资源管理器窗格中。
在这一点上,Auth0.swift所包含的功能现在对你的应用程序可用。一旦你完成了所有必要的Auth0设置,你将开始使用它。
添加一个属性列表来存储Auth0凭证
为了使用Auth0来验证用户,你的应用程序需要。
- 与适当的Auth0租户通信,并且
- 向该服务器识别自己。
你通过向应用程序提供该租户的标识符,一个被称为域的值,以及应用程序的标识符,即客户端ID来实现这一目的。Auth0.swift希望能在一个属性列表(一个 .plist
文件)中找到这些值,所以我们来创建一个。
🛠 右键单击(或控制单击)项目资源管理器中的SwiftUI Login Demo文件夹,选择**"新文件**",创建一个新的属性列表文件...。
🛠 在出现的窗口中,确保选择iOS标签。向下滚动图标列表,直到你看到属性列表图标。选择它,然后点击下一步。
🛠 命名该文件 Auth0.plist
并点击Create来创建该文件。
Xcode将以表格的形式显示新的 Auth0.plist
文件以表格的形式显示。让我们在表中添加两行,这将容纳域和客户ID值。
🛠 将光标移到根行上,显示出**"+**"按钮。点击两次 "+"按钮,增加两行。
🛠 在这两行中输入以下值
- 第1行
- 键:
Domain
- 类型:
String
- 值:暂时留空。你将从Auth0仪表板上得到这个值。
- 键:
- 第2行
- 钥匙:
ClientId
- 类型:
String
- 值:暂时留空。你将从Auth0仪表板上得到这个值。
- 钥匙:
你的Auth0
plist文件应该看起来像这样。
设置Auth0以与你的应用程序整合
现在你已经设置了应用程序与Auth0一起工作,现在是时候设置你的Auth0租户与该应用程序一起工作了。为了实现这一目标,你要做以下工作。
- 将该应用添加到你的Auth0仪表板的注册应用列表中
- 收集两个信息,应用程序将需要把登录/注销委托给Auth0。
- 你的租户的域名
- Auth0将分配给该应用程序的客户ID
- 向Auth0提供必要的回调URL以联系该应用:一个是在登录过程结束时调用,另一个是在注销过程结束时调用。
你需要一个Auth0账户来完成这一步。再一次,你可以免费注册一个Auth0账户我们已经非常小心地使这个过程尽可能地无痛。
将应用程序添加到应用程序列表中
🛠 登录Auth0仪表板,从页面左侧的菜单中选择应用→应用。
现在你将进入 "应用程序"页面,其中列出了你在Auth0注册的所有应用程序。让我们把你的应用程序添加到列表中。
🛠 点击页面右上方的创建应用程序按钮,开始注册新应用程序的过程。
你会看到这个对话框出现。
🛠 你需要提供两个信息才能继续。
- 在名称栏中输入一个应用程序的名称。可能最简单的是使用与你的Xcode项目相同的名称(如果你一直在遵循我的例子,使用SwiftUI Login Demo这个名称)。
- 指定应用程序的类型,在这种情况下,它是Native。
🛠 点击创建。应用程序的快速启动页面将出现。
这个页面为你提供了几个不同平台的现成项目,你可以将其作为将认证委托给Auth0的应用程序的基础。在这个练习中,你不会使用它们中的任何一个;相反,你将利用几个Auth0库并自己编写代码。这样做更有教育意义,更重要的是,更有乐趣。
🛠 单击 "设置"选项卡,这将带你到这个页面。
你要在这个页面上做两件关键的事情。
- 获取应用程序需要知道的关于Auth0的信息,以及
- 提供Auth0需要知道的关于该应用的信息。
让我们来处理第一件事。获取应用程序需要的信息,即域名和客户ID,你将把它们输入你先前创建的属性列表文件中。
🛠 复制Domain字段的内容,然后切换到Xcode,打开Auth0
属性列表,并将你复制的Domain值粘贴到Domain行的Value字段。
🛠 接下来,回到Auth0仪表板,复制Client ID字段的内容,然后切换到Xcode,将你复制的域值粘贴到属性列表中的ClientId行的Value字段。
🛠 返回到Auth0仪表板,向下滚动到应用程序URI部分。
这是你向Auth0提供它需要知道的关于你的应用程序的两个信息的地方。
- **回调URL:**用户成功登录后Auth0将重定向到的URL。可以有不止一个这样的URL。
- **注销URL:**用户注销后Auth0将重定向到的URL。可以有多个。
在这一点上,你可能在想。"等一下--我在用SwiftUI写一个iOS应用。它没有你用URL导航到的网页,而是视图!"
你说得很对。对于原生应用程序,回调和注销URL是同一个字符串,Auth0将该字符串发送给应用程序,以通知它用户已经登录或注销。
本机iOS应用程序用于回调URL和注销URL的字符串都遵循这种格式。
{BUNDLE_IDENTIFIER}://{YOUR_DOMAIN}/ios/{BUNDLE_IDENTIFIER}/callback
要构建这个字符串,你需要你的应用程序的捆绑标识符。
🛠在Xcode中,点击项目导航器中的项目,在Targets菜单中点击项目,并选择General标签。复制捆绑标识符的值,你可以在中心窗格顶部附近的身份部分的捆绑标识符字段中找到它。
🛠 复制上面的URL格式字符串,并进行以下修改,以创建一个新的URL。
- 将
{BUNDLE_IDENTIFIER}
替换为你复制的捆绑标识符。注意{BUNDLE_IDENTIFIER}
在URL中出现两次--两次都要替换。 - 替换为
{YOUR_DOMAIN}
用你的租户的域名。
🛠 在允许回调URLs和允许登录URLs字段中输入你刚刚构建的URL。记住,两个字段都要输入相同的URL。
🛠 你已经完成了本页需要做的一切。向下滚动到页面的底部,点击保存更改按钮。
如果你的租户没有任何用户,请创建一个用户
如果你刚刚创建了一个Auth0账户,你的租户就不会有任何用户账户。你至少需要一个用户账户才能登录到应用程序。按照这些步骤创建一个用户。
🛠 在Auth0仪表板左侧的菜单中,选择用户管理→用户。
将出现 "用户"页面。它列出了所有注册到你租户的用户。如果没有用户,你会看到 "你还没有任何用户 "的信息。
🛠 单击 "创建用户"按钮,创建一个新用户,这将使这个对话框出现。
🛠 为用户输入一个电子邮件地址和密码。连接的唯一选项将是用户名-密码-认证,所以保持原样。记下这个电子邮件地址和密码--你将用它们来登录应用程序。
🛠 点击创建按钮来创建用户。该用户的详细信息页面将出现。
这就解决了你在Auth0仪表板上需要做的所有设置。现在是时候回到Xcode和应用程序中去了。
添加认证
随着所有设置的完成,是时候回到编码中了。在这一步中,我们将把应用程序转换为一个使用Auth0来记录用户进出的应用程序。
导入Auth0库
🛠 在ContentView
的开头附近找到这一行 ...
import SwiftUI
...并在后面添加这个 import
语句紧随其后。
import Auth0
这一补充将使应用程序能够使用Auth0
对象及其方法和属性。
更新 login()
方法
该 login()
方法只是模拟了登录过程。让我们把它变成现实。
🛠 打开ContentView
,将当前的 login()
方法,用这个方法取代当前的方法。
func login() {
Auth0 // 1
.webAuth() // 2
.start { result in // 3
switch result {
// 4
case .failure(let error):
print("Failed with: \(error)")
// 5
case .success(let credentials):
self.isAuthenticated = true
print("Credentials: \(credentials)")
print("ID token: \(credentials.idToken)")
}
}
}
下面的注释与login()方法中的编号注释相对应。
- Auth0包的
Auth0
对象为认证过程提供了方法。这些方法中的许多都是执行认证的一个必要步骤,你可以把这些方法连锁起来,以完成不同的认证任务。 webAuth()
是该链中的第一个方法。它创建了一个WebAuth
对象,启动了通用登录。它需要租户的域名和应用程序的客户端ID,它从Auth0
属性列表中收集这些信息。start()
是呈现登录框的方法。它接受一个闭包,其唯一的参数代表用户尝试登录的结果。两个可能的结果--登录失败和登录成功--都在闭包中处理。- 我们在失败的情况下保持简单。在登录不成功的情况下,应用程序只是在调试控制台上打印出一条错误信息。
- 如果用户成功登录,会发生两件事。
- 应用程序接收用户的凭证,这是一个关于用户的信息集合。其中一个凭证是ID令牌,它是用户已被验证的证明。目前,该应用程序将简单地使用
credentials
'idToken
属性将ID令牌打印到调试台;在以后的修订中,它将从令牌中提取用户的姓名、电子邮件地址和图片URL。 isAuthenticated
状态变量被设置为true
,这一变化导致 UI 更新为 "已登录 "视图。
- 应用程序接收用户的凭证,这是一个关于用户的信息集合。其中一个凭证是ID令牌,它是用户已被验证的证明。目前,该应用程序将简单地使用
更新 logout()
的方法
就像你对 login()
所做的那样,现在是时候给这个 logout()
方法的真正功能。
🛠用这个方法替换当前的 logout()
方法替换为这个方法。
func logout() {
Auth0 // 1
.webAuth() // 2
.clearSession { result in // 3
switch result {
// 4
case .failure(let error):
print("Failed with: \(error)")
// 5
case .success:
self.isAuthenticated = false
}
}
}
下面的注释与logout()方法中的编号注释相对应。
- 我们再次从
Auth0
对象中链入方法。 - 就像在
login()
,webAuth()
是链条中的第一个方法,我们再次用它来激活通用登录。 clearSession()
完成注销的实际工作。就像start()
中的方法login()
,clearSession()
中的方法一样,需要一个带有单个参数的闭包,代表该请求的结果。- 如同
login()
中的方法一样,如果系统不能将用户注销,应用程序只是打印出一条错误信息。 - 如果用户成功注销,
isAuthenticated
状态变量被设置为false
,这一变化导致用户界面更新为 "已注销 "视图。
测试更新后的应用程序
🛠 运行应用程序,以确认该应用程序确实能验证用户。这一次,当你按下登录按钮时,不是直接进入 "已登录 "视图,而是看到通用登录屏幕。你需要输入一个有效的用户名和密码才能看到这第二个屏幕。
在你登录后看一下Xcode的调试窗口。你会看到这个方法的 login()
方法的 print()
函数的输出,它输出了credentials
对象的内容和它的idToken
属性。
Credentials: Credentials(accessToken: "<REDACTED>", tokenType: "Bearer", idToken: "<REDACTED>", refreshToken: nil, expiresIn: 2022-03-20 04:38:25 +0000, scope: Optional("openid profile email"), recoveryCode: nil)
ID token: eyJhbGciOiJSUzI1NiIsInR5cC...
注意,当 print()
函数用来输出credentials
的内容时,accessToken
和idToken
属性的值被替换为字符串 <REDACTED>
.理想情况下,你应该在应用程序进入 print()
函数,但许多开发者经常忘记这一步骤。恶意的一方可以使用工具来捕获生产应用程序中的 print()
函数的输出;这就是为什么Credentials
实例在打印时要编辑其accessToken
和idToken
属性的值。
credentials
有一个 属性,包含一个以空格分隔的scope
OpenID Connect(OIDC)作用域列表--用于访问有关用户的详细信息的授权--Auth0已经授予该应用程序。除非你另外指定,Auth0.swift默认在登录用户时请求以下作用域。
openid
:授权使用OIDC来验证用户的身份profile
:授权访问用户的姓名信息email
:授权访问用户的电子邮件地址
为了确认应用程序在登录用户后收到了一个ID令牌,我们打印它的值。我们将在下一步用它来获取用户的姓名、电子邮件地址和图片。
警告:🚨当你在学习认证过程或构建应用程序时,将ID令牌的值打印到调试控制台是没有问题的。请确保你删除
print()
语句--特别是那些打印敏感信息的语句,如ID令牌--在投入生产之前
到目前为止,你已经创建了一个基于SwiftUI的iOS应用,它使用Auth0来实现基本的登录和注销功能。在本教程的第二部分,你将赋予该应用获取登录用户的信息并在屏幕上显示的能力。