【发布时间】:2022-07-08 21:39:57
【问题描述】:
我正在使用 Swift 开发一个应用程序,以配合我正在进行的项目。我们想通过 Steam OpenID 处理登录过程。在网站上(使用 Angular 构建)它可以完美运行,但我在应用程序部分遇到了一些问题。
这是我的问题:
我们的后端不会在每次尝试时都为我提供令牌。
它通过和失败似乎是相当随机的,但总的来说,它是关于其他所有尝试的。
我怀疑我们后端的 OpenID 库有问题,所以我自己在 Steam 的端点上进行了多次尝试,但行为完全一样。
这是我的代码:
这在登录按钮点击时调用:
var session: ASWebAuthenticationSession?
func signIn() {
let scheme = "myauth"
let authUrl = URL(string: "https://steamcommunity.com/openid/login
?openid.ns=http://specs.openid.net/auth/2.0
&openid.claimed_id=http://specs.openid.net/auth/2.0/identifier_select
&openid.identity=http://specs.openid.net/auth/2.0/identifier_select
&openid.return_to=https://mywebsite.com/appauth
&openid.realm=https://mywebsite.com
&openid.mode=checkid_setup")!
self.session = ASWebAuthenticationSession.init(url: authUrl, callbackURLScheme: scheme, completionHandler: { callbackURL, error in
guard error == nil, let successURL = callbackURL else {
print("Error: ASWebAuthSession returned with: \(error!)")
return
}
var queryItems = URLComponents(string: successURL.absoluteString)!.queryItems!
HttpService.getSteamResponse(queryItems: queryItems)
})
session?.presentationContextProvider = self
session?.prefersEphemeralWebBrowserSession = true
self.session?.start()
}
这是引用的函数:
static func getSteamResponse(queryItems: [URLQueryItem]) {
var mutatedItems = queryItems
if var item = queryItems.enumerated().first(where: {$0.element.name == "openid.mode"}) {
item.element.value = "check_authentication"
mutatedItems[item.offset] = item.element
} else {
print("Error: Steam check has no item 'openid.mode'")
}
var urlComps = URLComponents(string: "https://steamcommunity.com/openid/login")!
urlComps.queryItems = mutatedItems
let url = urlComps.url!
URLSession.shared.dataTask(with: url) { (data, response, error) in
guard let data = data else {
debugPrint("Error: Steam check responded with: \(String(describing: error))")
return
}
if let httpResponse = response as? HTTPURLResponse{
print("Info: Steam check responsed with: \(httpResponse.statusCode)")
}
print("Info: Steam check data: \(String(decoding: data, as: UTF8.self))")
}.resume()
}
这包括一些可能没有必要的额外检查,并且在某些方面可能不是很优化(我仍在学习 Swift),但总而言之,它应该可以正常工作(并且确实......有时)
更多信息:
请注意,我用占位符替换了指向我们项目的实际链接。
据我了解,ASWebAuthenticationSession 回调确实只需要一个 URL 方案,我将其替换为 myauth。因为我注意到 Steam(或一般的 OpenID?)不喜欢自定义 URL 方案,所以我改用 https://mywebsite.com/appauth,它使用 301 重定向到带有所有参数的 myauth://foobar.com 之类的东西,所以我可以在应用程序中接收它们(我猜这个也可以通过通用链接工作,但我还没有付费开发帐户。
现在,当我运行此代码时,我无法获得一致的响应。它始终是 200 和 ns:http://specs.openid.net/auth/2.0 以及看似随机的 is_valid:false 或 is_valid:true。
我运行了多次,尝试在中间重新部署应用程序,甚至擦除模拟器设备,但我无法获得一致的结果。
很遗憾,我只能尝试这么多次,因为 Steam 将在大约 15 次登录后阻止从我的网络登录。
在我上次试用时,我收到了false, false, true, false, true。
我猜可能会有一些我没有注意到的并发问题。
感谢您对此主题的任何帮助!
【问题讨论】:
标签: swift authentication openid steam