AsWebAuthenticationsession 支持通用链接吗?

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

我使用 AsWebAuthenticationsession 从另一个应用程序到我的应用程序进行身份验证。我打开 AsWebAuthenticationsession,它会重定向我的应用程序的通用链接。问题是当它重定向我的应用程序通用链接时,它要求打开应用程序商店。当它重定向时我想关闭会话。但 AsWebAuthenticationsession 只采用自定义 URL 方案。我怎样才能安全地处理它(因为自定义 URL 方案不安全:RFC8252 7.1

ios swift oauth-2.0 ios-universal-links aswebauthenticationsession
3个回答
5
投票

我可以确认这在 iOS 14 或更高版本中有效,但尚未在早期版本上进行测试。

初始化

ASWebAuthenticationSession
时,可以传入
callbackURLScheme: "https"

当身份验证提供程序重定向到您的通用链接时,您的应用程序委托的

application(_:continue:restorationHandler:)
将使用正确的重定向 URL 触发,但是
ASWebAuthenticationSession
的完成处理程序不会 触发,因此身份验证对话框仍保留在屏幕上.

您需要手动保存对

ASWebAuthenticationSession
cancel()
的引用才能将其关闭。


0
投票

你可以尝试一下这个方法

添加一个单例类来处理此回调

SceneDelegate.swift

@available(iOS 13.0, *)

func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {

    // handle here

    OAuthManager.instance.callBackUserActivity(userActivity: userActivity)

}

OAuthManager.swift

import Foundation

import AuthenticationServices



protocol UserActivityListener {

func callBackUserActivity( userActivity : NSUserActivity )

}



class OAuthManager {

public static let instance = OAuthManager()

var asWebSession: ASWebAuthenticationSession?

}

extension OAuthManager : UserActivityListener {

func callBackUserActivity(userActivity: NSUserActivity) {

    // Get URL components from the incoming user activity.

    guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,

          let incomingURL = userActivity.webpageURL,

          let components = NSURLComponents(url: incomingURL,    resolvingAgainstBaseURL: true) else {

        return

    }

    

    // Check for specific URL components that you need.

    guard let path = components.path,

          let params = components.queryItems else {

        return

    }
    // cancel your ASWebAuthenticationSession
    asWebSession?.cancel()


    print("path = \(userActivity.webpageURL)")



    if let token = params.first(where: { $0.name == "token" })?.value {

        print("token = \(token)")

    }

  }


 }

你的ViewController.swift

class YourViewController: UIViewController {
// set your instance
var oauthManager = OAuthManager.instance


private func startSignInAsWebAuthSession() {
    let callbackURLScheme = "YOURAPP"
    guard let authURL = URL(string: "YOUR URL LINK") else { return }
        
        self.oauthManager.asWebSession = ASWebAuthenticationSession.init(url: authURL, callbackURLScheme: callbackURLScheme,completionHandler: { callbackURL, error in
            // we dont listen to the call back, this web authentication session only open for login only
        })
        
        oauthManager.asWebSession?.prefersEphemeralWebBrowserSession = true
        oauthManager.asWebSession?.presentationContextProvider = self
        oauthManager.asWebSession?.start()
}
}

extension YourViewController:    ASWebAuthenticationPresentationContextProviding {
   func presentationAnchor(for session: ASWebAuthenticationSession) ->     ASPresentationAnchor {
       ASPresentationAnchor()
    }
  }

0
投票

今天(2024 年)我使其工作的唯一方法(特别是使用 SwiftUI)是在 AWS 上创建 lambda 无服务器服务,我使用路径

auth\appLogin
注册了重定向 URL,在我的例子中,该路径处理来自 OAuth 2.0 的响应响应类型是
code
,所以我需要调用另一个 API 来获取
accesss_token
,然后以重定向作为在我的应用程序上注册的 URL 方案进行响应:

           resolve({
                statusCode: 302,
                headers: {
                    'Location': `myapp://callback?access_token=${JSON.parse(body).access_token}`
                }
            });

这是我的 SwiftUI 代码

       if let authURL = URL(string: "\(baseURL)?response_type=\(responseType)&client_id=\(clientId)&redirect_uri=\(redirectUrl)&scope=\(scopesString)") {
           let scheme = "myapp" // Your app's custom URL scheme
           let session = ASWebAuthenticationSession(url: authURL, callbackURLScheme: scheme) { callbackURL, error in
               guard error == nil, let callbackURL = callbackURL else {
                   print("Authorization failed: \(String(describing: error))")
                   return
               }
               
               // Handle the authorization code from the callbackURL
               let queryItems = URLComponents(string: callbackURL.absoluteString)?.queryItems
               if let access_token = queryItems?.first(where: { $0.name == "access_token" })?.value {
                   print("Authorization token: \(access_token)")
               }
           }
           
           session.presentationContextProvider = contextProvider
           session.start()
       }

还记得注册您的 URL 方案 :

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