AccountSDKIOSWeb 4.2.1

AccountSDKIOSWeb 4.2.1

Bogdan NiculescuMichal OleniaczMarcin_Grzeskowiak 维护。



 
依赖
JOSESwift~> 2.4.0
日志记录~> 1.4.0
 

  • Schibsted

Schibsted 账户 iOS SDK

Build Status GitHub release (latest by date) Platform License: MIT

使用 ASWebAuthenticationSession 通过网页流实现 Schibsted 账户 iOS SDK 的新实现。

API 文档可在此处找到 此处

入门

要在您的应用程序中实现 Schibsted 账户的登录功能,请首先查看我们的 入门文档。这将帮助您创建客户端并配置必要的数据。

注意:此 SDK 要求您的客户端在 Self Service 中注册为 public_mobile_client(有关更多帮助,请参阅 入门文档}

需求

  • iOS 12.0+

安装

Swift包管理器: .package(url: "https://github.com/schibsted/account-sdk-ios-web")

CocoaPods pod 'AccountSDKIOSWeb'

用法

登录用户并获取配置文件数据

let clientConfiguration = ClientConfiguration(environment: .pre,
                                              clientId: clientId,
                                              redirectURI: redirectURI)
let client = Client(configuration: clientConfiguration) 
let contextProvider = ASWebAuthSessionContextProvider()
let asWebAuthSession = client.getLoginSession(contextProvider: contextProvider, withSSO: true, completion: { result in
    switch result {
    case .success(let user):
        print("Success - logged in as \(String(describing: user.uuid))")
        self.user = user
    case .failure(let error):
        print(error)
    }

    user.fetchProfileData { result in
        switch result {
        case .success(let userData):
            print(userData)
        case .failure(let error):
            print(error)
        }
    }
})

asWebAuthSession.start()

在注销时通知

let userDelegate: UserDelegate = MyUserDelegate()
user?.delegates.addDelegate(userDelegate)
self.userDelegate = userDelegate // Needs to be retained

class MyUserDelegate: UserDelegate {
    func userDidLogout() {
        print("Callback will be invoked when user is logged out")
    }
}

关于使用自定义URI方案的注意事项

当使用自定义URI作为重定向URI时,操作系统处理的是打开与链接关联的应用,而不是触发ASWebAuthenticationSession回调。这导致ASWebAuthenticationSession视图没有正确关闭,需要手动关闭。

  1. 获取对ASWebAuthenticationSession的引用并启动它。

    func handleLoginResult(_ result: Result<User, LoginError>) {
        switch result {
        case .success(let user):
            print("Success - logged-in as \(user.uuid)!")
            self.user = user
        case .failure(let error):
            print(error)
        }
    }
    
    let contextProvider = ASWebAuthSessionContextProvider()
    asWebAuthSession = client.getLoginSession(contextProvider: contextProvider, withSSO: true, completion: handleLoginResult)
    asWebAuthSession.start() // this will trigger the web context asking the user to login
  2. 将响应处理为传入的URL,例如,通过你的应用代理的application(_:open:options:)方法。

    func application(_ application: UIApplication,
                     open url: URL,
                     options: [UIApplicationOpenURLOptionsKey : Any] = [:] ) -> Bool {
        client.handleAuthenticationResponse(url: url) { result in
            DispatchQueue.main.async {
                asWebAuthSession.cancel() // manually close the ASWebAuthenticationSession
            }
            handleLoginResult(result)
        }
    }
  3. 当实现瑞典BankID身份验证时,父应用必须捕获重定向URI,并返回时不需要执行任何操作。请确保在BankID重定向时不调用handleAuthenticationResponse。从BankID重定向回父应用使用的URI方案格式如下:{app_uri_scheme}:/bankId。下面是一个代码示例:

    func handleOnOpenUrl(url: URL) {
        if url.pathComponents.contains("bankId") {
            return
        }
        
        client.handleAuthenticationResponse(url: url) { result in
            DispatchQueue.main.async {
                asWebAuthSession.cancel() // manually close the ASWebAuthenticationSession
            }
            handleLoginResult(result)
        }
    }

外部获取令牌

令牌可以外部获得并注入到SDK中,用于已创建的用户。在测试场景中这可能很有用。为此,首先需要使用以下请求启动网页登录流程:

GET "${BASE_URL}/oauth/authorize?client_id=${CLIENT_ID}&redirect_uri=${REDIRECT_URI}&response_type=code&scope=openid%20offline_access&state=${state}&nonce=${nonce}&code_challenge=${CODE_CHALLENGE}&code_challenge_method=S256&prompt=select_account"

其中:BASE_URL - Schibsted Account环境的基准URL;client_id - 公共移动客户端ID;redirect_uri - 给定客户端的重定向URI;state - 客户端发送的字符串值,用于保护最终用户免受CSRF攻击。这是一个由10个字符(字母和数字)随机生成的字符串;nonce - 客户端发送的字符串值,包含在生成的ID令牌中作为声明。客户端必须验证此值以减轻令牌重放攻击。这是一个由10个字符(字母和数字)随机生成的字符串;code_challenge - 根据code_verifier计算出的PKCE

在完成网页流程后,返回的URL将包含查询参数statecode。可以使用以下请求获取令牌:

curl {BASE_URL}/oauth/token \
   -X POST \
   -H "X-OIDC: v1" \
   -d "client_id={client_id}" \
   -d "grant_type=authorization_code" \
   -d "code={code_from_login_flow}" \
   -d "code_verifier={code_verifier}" \
   -d "redirect_uri={redirect_uri}"

其中code_verifier用于计算code_challenge的相同值。它可以是一个由60个字符(字母和数字)随机生成的字符串。

配置日志记录

此SDK使用SwiftLog,允许你轻松自定义日志记录。可以通过以下代码修改记录器,例如更改日志级别:

SchibstedAccountLogger.instance.logLevel = .debug

如何工作

此SDK实现了通过OpenID Connect身份提供商进行用户身份验证的最佳实践

  • 它使用ASWebAuthenticationSession。这允许应用程序之间进行单点登录,通过cookie识别用户为Schibsted账户的回应用户。在iOS 13及以上版本中,此行为可以被禁用,通过在Client.getLoginSession(withMFA:loginHint:extraScopeValues:withSSO:completion:)中使用withSSO: false来移除额外的用户提示,允许使用Schibsted账户进行登录。
  • 在完成用户身份验证后,用户令牌将安全地存储在钥匙串存储中。
    • 根据规范验证ID令牌。ID令牌的签名(是一个JWS)由库JOSESwift验证。

    • 可以通过AuthenticatedURLSession.dataTask(with: URLRequest, completionHandler: ...对后端服务进行经过身份验证的请求。SDK会自动将用户访问令牌作为Bearer令牌注入HTTP授权请求头中。如果访问令牌因过期等原因被拒绝,并以401 Unauthorized响应,SDK会尝试使用刷新令牌来获取新的访问令牌,然后再次尝试请求。

      注意:如果刷新令牌请求失败,由于刷新令牌本身已过期或已被用户无效化,SDK将注销用户。

  • 当应用启动时,SDK可以通过尝试从钥匙串存储中读取之前存储的令牌,来继续上次登录的用户。这将在应用的启动时通过调用Client.resumeLastLoggedInUser(completion: @escaping (User?) -> Void)一次来处理。

简化登录

配置简化登录

先决条件:应用需要位于同一个Apple开发账户下,才能访问共享密钥链。

  1. 在您的应用程序目标中,添加密钥链共享功能,并将密钥链组设置为com.schibsted.simplifiedLogin
  2. 创建客户端时,传递额外的参数appIdentifierPrefix。它通常是团队标识前缀相同 - 由苹果分配的10位数字和字母组合。
let client = Client(configuration: clientConfiguration, appIdentifierPrefix: "xxxxxxxxxx") 
  1. 创建SimplifiedLoginManager并在任何需要向用户展示SL的情况下调用getSimplifiedLogin方法。
    let context = ASWebAuthSessionContextProvider()
    let manager = SimplifiedLoginManager(client: client, contextProvider: context, env: clientConfiguration.env) { result in
            print("Catch login result \(result)")
    }
    manager.requestSimplifiedLogin() { result in
        switch (result) {
        case .success():
            print("success")
        case .failure(let error):
            print("Catch error from presenting SL \(error)")
        }
    }

如果您想在特定的UIWindow上展示简化登录UI,您需要通过调用requestSimplifiedLogin方法传递可选的window参数。

跟踪

Account SDK执行一些内部跟踪(主要是简化登录)并允许在客户端初始化期间设置TrackingEventsHandler。为了满足这一点,您可以自己实现它或使用已实现的某个版本。

内部:对于身份SDK,有一个可用的内部Schibsted跟踪实现,请访问此处。它集成了最新的Account SDK与最新的iOS Pulse Tracking SDK。

本地化

简化登录提供以下本地化支持

  1. 🇳🇴 挪威语 bokmål
  2. 🇸🇪 瑞典语
  3. 🇫🇮 芬兰语
  4. 🇩🇰 丹麦语
  5. 🇬🇧 英语(默认)

本地开发

设置

先决条件

  1. 您只需要安装了命令行工具的Xcode。它与版本13.4.1完美兼容。

步骤

  1. 克隆仓库
  2. 打开位于项目文件夹中的 workspace.xcworkspace 文件。它包含两个项目:AccountSDKIOSWeb,即SDK自身,以及用于演示的ExampleWeb。
  3. 要在模拟器上运行演示应用程序,选择ExampleWeb方案,并将目标选择为iPhone或iPad。使用播放按钮或按command + R运行应用程序。
  4. 如果Xcode无法解决包依赖关系,点击它们并手动解决。

单元测试

  1. 存在两种带有测试的方案。要运行单元测试,请选择其中一种并按 command + U

如何发布SDK

准备工作

  1. 要成功将SDK的pod发布到CocoaPods仓库,您首先需要在计算机上设置pod trunk。请参阅 https://guides.cocoapods.org.cn/making/getting-setup-with-trunk.html
  2. 您应该在CocoaPods仓库中的库中添加为所有者。请向用户访问团队提出申请,他们可以给您正确的权限。

发布步骤

  1. 确保所有即将发布的变化都已合并到master分支。
  2. Version.swiftAccountSDKIOSWeb.podspec文件中更新新的SDK版本号。将此更改提交到master分支。
  3. 通过GitHub创建一个新发布
    1. 将版本号作为标签名称输入,并在发布说明中包括所有重要更改。
  4. 在您的本地机器上运行pod trunk push AccountSDKIOSWeb.podspec来发布pod。