ASWebAuthenticationSession 重定向行为不一致

问题描述 投票:0回答:1

我们为网站提供了一个简单的 WKWebView,具有多种登录选项 - Google、Microsoft 和 DLRG(德国救生协会)。 为了进行身份验证,身份验证 URL 在

ASWebAuthenticationSession
中打开,用户可以通过所选方法登录并返回到所有登录的网站。这里有一个大问题,用户仅在弹出窗口中登录。如果我关闭 ASWebAuthenticationSession 弹出窗口,用户将返回到登录页面并可以从头开始。

更大的问题是,这不一致。有时它可以工作并且用户在

ASWebAuthenticationSession
过程完成后登录,但有时用户在弹出窗口中登录。 我有两部手机要测试,iPhone 11 和 iPhone 13 mini,在 iPhone 11 上,除了 Google 之外的所有内容每次都能正常工作,而在 iPhone 13 上,有时可以正常工作,有时我会登录到弹出窗口。这种行为是在具有相同登录数据的相同 TestFlight 版本以及两个设备最初注销时发生的。这让我发疯!

这是相关代码:

session = ASWebAuthenticationSession(url: url, callbackURLScheme: "com.my.app") { callbackURL, error in
            if let error {
                print("We have an error authenticating: \(error.localizedDescription)")
                return
            }
            
            print("Session done and successfull")
        }
        
        session?.prefersEphemeralWebBrowserSession = true
        session?.presentationContextProvider = authenticationManager
        session?.start()

我们添加了带有“applinks”变量(即通用链接)的“关联域”功能,因此当用户点击包含我们标识符的链接时,应用程序将被打开。因此,

callbackURLScheme
将被完全忽略(我已经尝试了 info.plist 中方案的所有可能的变体),并且只有通过弹出窗口上的“取消”按钮关闭时才能访问打印语句。

在它确实有效的情况下,我通过此 SwiftUI 方法注册来自“外部”的重定向 url/uri:

.onOpenURL { url in
                webViewModel.openURL(url)
            }

然后我关闭弹出窗口(会话),加载网址并登录用户。当它不起作用时,

.onOpenURL
函数不会注册任何内容。


所以它有效,但高度不一致。我想也许是后端功能出了问题,但我和负责人谈过,他解释了背后的逻辑,我认为是iOS方面的问题。请注意,浏览器或 Android 应用程序不存在任何这些问题,因此重定向可以正常工作。但如果是在iOS端,你可以看到只需要几行代码就可以自定义

ASWebAuthenticationSession

如果您有任何想法或线索,请告诉我!谢谢你! :)

编辑:这个家伙here似乎也有同样的问题,它加载了ASWebAuthenticationSession中的内容,并说这是由于Google的2fa。我们使用 2fa 并遇到同样的问题,但在没有 2fa 的 Microsoft 中也会发生这种情况。所以我不确定这是否与此有关。

swift oauth-2.0 google-oauth aswebauthenticationsession
1个回答
1
投票

如果您使用 HTTPS 重定向 URL,也许可以尝试此代码。当您收到深层链接响应时,调用 startLogin 来调用窗口并调用 endLogin。

import Foundation
import AuthenticationServices

class LoginSession: NSObject, ASWebAuthenticationPresentationContextProviding {
    
    private var authSession: ASWebAuthenticationSession?
    private var error: OAuthError?
    
    func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
        return ASPresentationAnchor()
    }

    func startLogin(authorizationRequestUrl: String) throws {

        self.error = nil
        authSession = ASWebAuthenticationSession(
            url: URL(string: authorizationRequestUrl)!,
            callbackURLScheme: "https",
            completionHandler: { (callbackUrl: URL?, error: Error?) in

                defer {
                    self.authSession?.cancel()
                    self.authSession = nil
                }

                if let errorCode = (error as? NSError)?.code {
                    if errorCode != ASWebAuthenticationSessionError.Code.canceledLogin.rawValue {
                        self.error = OAuthError(code: "login_error", message: "ASWebAuthenticationSession error code \(errorCode)")
                    }
                }
            }
        )
     
        authSession?.presentationContextProvider = self
        authSession?.start()
    }

    func endLogin() {
        
        self.authSession?.cancel()
        self.authSession = nil
    }
}

请注意,此代码仅处理登录窗口。您需要使用深层链接响应 URL 单独兑换代币代码。

请注意,您无法使用网站登录移动应用程序。例如,如果网站发布 cookie,WKWebView 将不会与上述登录窗口共享它们,因为 WKWebView 是私人浏览会话并使用不同的 cookie jar。

有关使用通用链接的 iOS 移动登录的更多信息,您可以运行我的代码示例并浏览随附的博客文章。请注意,登录响应需要

user gesture
才能可靠地返回到应用程序。这通常由某种
interstitial page
来处理。

© www.soinside.com 2019 - 2024. All rights reserved.