Okta AppAuth-iOS 包装库
此库是对 AppAuth-iOS SDK 的包装,用于作为 OAuth 2.0 + OpenID Connect 提供者与 Okta 通信,并遵循使用 授权代码流 + PKCE 的原生应用的当前最佳实践。
*Okta 使用一个带有注销功能的 AppAuth-iOS 分支版本。有关该待加入功能的更多详细信息,请参阅 #259。
有关更多信息,请参阅我们文档中的 Okta + iOS 页面。
目录
入门
将 Okta AppAuth 包装库安装到您的项目中很简单。将此库包含到项目中最快的方法是通过 CocoaPods。
您还需要
- 一个 Okta 帐户,也称为 组织(如果您需要,可以免费注册一个 开发组织)。
- 一个Okta应用程序,配置为原生应用。这是在Okta开发控制台中完成的,您可以在此处找到说明这里。在跟随向导时,使用默认属性。它们被设计为与我们的示例应用程序一起使用。
使用Cocoapods
只需将以下行添加到您的Podfile
pod 'OktaAuth'
然后将其安装到您的项目中
pod install
处理重定向
为了从网络浏览器将应用重定向回您的应用,您必须指定一个独特的URI。为此,打开应用程序包中的Info.plist
并设置一个URL Scheme为重定向URI的模式。
例如,如果您的重定向URI是com.okta.example:/callback
,则URL Scheme将是com.okta.example
。
接下来,更新您的AppDelegate
以包含以下函数以允许重定向发生
// AppDelegate.swift
import OktaAuth
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any]) -> Bool {
return OktaAuth.resume(url: url, options: options)
}
使用指南
有关本库功能和认证流程的概述,请参阅我们的开发文档。
您还可以浏览完整的API参考文档。
配置参考
您有多种方法可以为图书馆进行配置,以便执行应用内的认证。您可以创建一个具有共享值的新的plist
文件或直接将配置传递给登录方法。
需要刷新令牌? 刷新令牌是一个特殊令牌,用于生成额外的访问和ID令牌。请确保在配置中包含offline_access
范围,以静默地在您的应用中续订用户的会话!
属性列表
最简单的方法是在应用包中创建属性列表。默认情况下,该库会检查文件Okta.plist
的存在,但任何属性列表文件都适用。请确保创建包含以下字段的文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>issuer</key>
<string>https://{yourOktaDomain}.com/oauth2/default</string>
<key>clientId</key>
<string>{clientId}</string>
<key>redirectUri</key>
<string>{redirectUri}</string>
<key>logoutRedirectUri</key>
<string>{logoutRedirectUri}</string>
<key>scopes</key>
<string>openid profile offline_access</string>
</dict>
</plist>
配置对象
或者,您可以创建一个包含所需值的字典
let config = [
"issuer": "https://{yourOktaDomain}/oauth2/default",
"clientId": "{clientID}",
"redirectUri": "{redirectUri}",
"logoutRedirectUri": "{logoutRedirectUri}",
"scopes": "openid profile offline_access",
// Custom parameters
"login_hint": "[email protected]"
]
API 参考
signInWithBrowser
通过简单地调用 signIn
来开始授权流程。默认情况下,此方法使用 Okta.plist
文件中指定的值
OktaAuth
.signInWithBrowser()
.start(view: self)
.then { tokens in
// tokens.accessToken
// tokens.idToken
// tokens.refreshToken
}
.catch { error in
// Error
}
或者使用通过 withPListConfig
参数指定的自定义 plist
文件
OktaAuth
.signInWithBrowser()
.start(withPListConfig: "CustomPlist", view: self)
.then { tokens in
// tokens.accessToken
// tokens.idToken
// tokens.refreshToken
}
.catch { error in
// Error
}
最后,使用字典而不是 plist
let config: [String: String] = [
// Your configuation
]
OktaAuth
.signInWithBrowser()
.start(withDictConfig: config, view: self)
.then { tokens in
// tokens.accessToken
// tokens.idToken
// tokens.refreshToken
}
.catch { error in
// Error
}
signOutOfOkta
您可以通过简单地调用 signOutFromOkta
来开始注销流程。此方法将结束用户在浏览器中的 Okta 会话。
重要:此方法不会清除或撤销 Okta 发行的令牌。请使用 revoke
和 clear
方法来终止用户在您应用程序中的本地会话。
// Redirects to the configured 'logoutRedirectUri' specified in Okta.plist.
OktaAuth
.signOutFromOkta()
.start(view: self)
.then {
// Additional signout logic
}
.catch { error in
// Error
}
与 signIn
方法类似,signOutOfOkta
也可以接受自定义 plist
或字典配置。
// Use a custom plist file
OktaAuth
.signOutFromOkta()
.start(withPListConfig: "CustomPlist", view: self)
.then {
// Additional signout logic
}
.catch { error in
// Error
}
// Use a dictionary object for configuration
let config: [String: String] = [
// Your configuation
]
OktaAuth
.signOutFromOkta()
.start(withDictConfig: config, view: self)
.then {
// Additional signout logic
}
.catch { error in
// Error
}
authenticate
如果您已经登录Okta并拥有有效的会话令牌,您可以通过调用authenticate(withSessionToken_succESSFULLY:)
来完成授权。默认情况下,此方法使用在Okta.plist
文件中指定的值。
OktaAuth
.authenticate(withSessionToken: sessionToken)
.start()
.then { tokens in
// tokens.accessToken
// tokens.idToken
// tokens.refreshToken
}
.catch { error in
// Error
}
与login
方法类似,authenticate(withSessionToken:)
可以接受自定义的plist
或字典配置
// Use a custom plist file
OktaAuth
.authenticate(withSessionToken: sessionToken)
.start(withPListConfig: "CustomPlist")
.then { tokens in
// tokens.accessToken
// tokens.idToken
// tokens.refreshToken
}
.catch { error in
// Error
}
// Use a dictionary object for configuration
let config: [String: String] = [
// Your configuation
]
OktaAuth
.authenticate(withSessionToken: sessionToken)
.start(withDictConfig: config)
.then { tokens in
// tokens.accessToken
// tokens.idToken
// tokens.refreshToken
}
.catch { error in
// Error
}
isAuthenticated
如果TokenManager中存储了有效的访问令牌,则返回true
。这是确定用户是否已成功登录您应用的最佳方式。
if !OktaAuth.isAuthenticated() {
// Prompt for sign in
}
getUser
调用OpenID Connect UserInfo端点,使用存储的访问令牌来返回用户声明信息。
OktaAuth.getUser() { response, error in
if error != nil {
print("Error: \(error!)")
}
if let userinfo = response {
// JSON response
}
}
introspect
调用 introspection 端点以检查指定令牌的有效性。
OktaAuth
.introspect()
.validate(token: token)
.then { isActive in
print("Is token valid? \(isActive)")
}
.catch { error in
// Error
}
refresh
由于访问令牌通常是短命的,您可以交换刷新令牌以获取新的令牌来刷新过期的令牌。请参阅配置参考以确保您的应用已正确配置此流程。
OktaAuth
.refresh()
.then { newAccessToken in
print(newAccessToken)
}
.catch { error in
// Error
}
revoke
调用撤销端点以撤销指定的令牌。
OktaAuth
.revoke(token: token) { response, error in
if error != nil {
print("Error: \(error!)")
}
if let _ = response {
print("Token was revoked")
}
}
tokens
令牌在钥匙链中安全存储,可以通过访问TokenManager检索。您可以随时通过调用与OktaAuth绑定的token
对象来请求它们。
OktaAuth.tokens?.accessToken
OktaAuth.tokens?.idToken
OktaAuth.tokens?.refreshToken
clear
通过从钥匙链中删除缓存的令牌来移除本地认证状态。
OktaAuth.clear()
开发
运行测试
要执行端到端测试,更新Okta.plist
文件以匹配先决条件中指定的配置。接下来,导出以下环境变量
export USERNAME={username}
export PASSWORD={password}
export CLIENT_ID={clientId}
export ISSUER=https://{yourOktaDomain}/oauth2/default
export REDIRECT_URI={redirectUri}
export LOGOUT_REDIRECT_URI={logoutRedirectUri}
# Run E2E end Unit tests
bash ./scripts/build-and-test.sh
注意: 您可能需要更新模拟器设备以匹配您的Xcode版本