And*_*dre 16 authentication token digital-signature swift
如何构建 swift POST 请求以满足 Sign In With Apple 令牌撤销要求?
我不确定 form-data、client_id、client_secret、token 或 token_type_hint 应该是什么。我能够实现“使用 Apple 登录”来创建用户,但对其中的撤销部分非常迷失。
我希望用 Swift 来执行这个客户端,因为那是最方便的。Firebase 可能正在开发一种内置于其 SDK 中的解决方案,但不确定这是否是适合使用 Firebase 的开发人员的通用解决方案。
https://developer.apple.com/documentation/sign_in_with_apple/revoke_tokens#url
编辑:要求来源https://developer.apple.com/support/offering-account-deletion-in-your-app
以下函数位于同一类 (ViewModel) 中。第一个是我的登录/注册流程。一些代码与 Firebase 流相关,基本上可以忽略,但您可以看到我抓取了 client_secret 的令牌字符串和随机数。第二个函数类似于令牌撤销的 POST 请求(从未显示的删除帐户函数调用)。有人使用这种方法/样板取得过成功吗?
在我的应用程序中点击按钮来测试下面的令牌撤销方法会返回状态代码 400。我无法使用此方法撤销令牌,并且我不确定还能做什么。
public func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
// Sign in using Firebase Auth
if let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential {
guard let nonce = currentNonce else {
print("Invalid state: A login callback was received, but no login request was sent.")
return
}
// JWT
guard let appleIDToken = appleIDCredential.identityToken else {
print("Unable to fetch identity token")
return
}
guard let idTokenString = String(data: appleIDToken, encoding: .utf8) else {
print("Unable to serialize token string from data")
return
}
let credential = OAuthProvider.credential(withProviderID: "apple.com", idToken: idTokenString, rawNonce: nonce)
Auth.auth().signIn(with: credential) { result, error in
if error != nil {
print(error!.localizedDescription)
return
}
else { // successful auth, we can now check if its a login or a registration
guard let user = Auth.auth().currentUser else {
print("No user was found.")
return
}
let db = Firestore.firestore()
let docRef = db.collection("Users").document(("\(user.uid)"))
docRef.getDocument{ (document, error) in
if let document = document, document.exists {
// User is just logging in, their db store exists
print("Successful Apple login.")
// Token revocation requirements
self.clientSecret = nonce
self.appleToken = idTokenString
if (self.isDeletingAccount == true) {
print("Is deleting account.")
self.isReauthenticated = true
}
self.isLogged = true
}
else { // document does not exist! we are registering a new user
db.collection("Users").document("\(user.uid)").setData([
"name": "\(appleIDCredential.fullName?.givenName ?? "")"
])
print("Successful Apple registration.")
self.clientSecret = nonce
self.appleToken = idTokenString
self.isLogged = true
}
}
}
}
}
}
// POST request to revoke user's Apple token
func appleAuthTokenRevoke(completion: (([String: Any]?, Error?) -> Void)? = nil) {
let paramString: [String : Any] = [
"client_id": Bundle.main.bundleIdentifier!, //"com.MyCompany.Name",
"client_secret": self.clientSecret,
"token": self.appleToken,
"token_type_hint": "access_token"
]
let url = URL(string: "https://appleid.apple.com/auth/revoke")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
do {
request.httpBody = try JSONSerialization.data(withJSONObject: paramString, options: .prettyPrinted)
}
catch let error {
print(error.localizedDescription)
completion?(nil, error)
}
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
let task = URLSession.shared.dataTask(with: request as URLRequest) { (data, response, error) in
guard let response = response as? HTTPURLResponse, error == nil else {
print("error", error ?? URLError(.badServerResponse))
return
}
guard (200 ... 299) ~= response.statusCode else {
print("statusCode should be 2xx, but is \(response.statusCode)")
print("response = \(response)")
return
}
if let error = error {
print(error)
}
else {
print("deleted accont")
}
}
task.resume()
}
Run Code Online (Sandbox Code Playgroud)
Note, I am not familiar with swift, please forgive me that I cannot post a good answer with swift. I found some guys are not clear about the parameters of revoke token API. Hope it will help someone who is not clear about those parameters.
\nThe three required values \xe2\x80\x8b\xe2\x80\x8bare required for appleid.apple.com/auth/revoke.
client_id: This is the App ID you can find in Apple Developer\'s Identifiers. Team ID is an excluded identifier.
\nclient_secret: A secret JSON Web Token (JWT) that uses the Sign in with Apple private key associated with your developer account. You need to create it using JWT and download a key file from developer.apple.com/account/resources/authkeys/list
token: A token that requires revoke. The token is access_token or refresh_token returned from auth/token.
As for the auth/token, there are two additional parameters as below
authorizationCode,类型为base64(like XXXXXXXXXXXXXXXXXXX)。在分配给 API 之前,应将其解码为utf-8(如) 。xxxxxxxxxxxx.0.zzzz.YYYYYYYYYYYYYYYYYYYauth/tokenauthorization_code. 对于刷新令牌验证请求,请使用refresh_token.Apps Using Apple ID最后,我们就可以成功调用revoke token api(appleid.apple.com/auth/revoke),并且删除Settings了.apple.com下的apple id绑定信息。并且可以找到 Node.js 示例Node.js 示例可以在这里
整个过程总结如下。
\nauth\\tokentoken\\revoke小智 6
适合任何想要使用 flutter、swift 或 React 实现帐户删除的人。
在继续阅读之前,请花点时间阅读完成撤销过程所需的两个 url 的 api 要求。
下面的链接展示了如何使用 firebase 函数在 iOS(swift) 和 firebase 上执行此操作。通过阅读它,您可以使用其他 SDK(即 flutter、react-native 等)实现解决方案。
但试图总结一下:-
2.您将使用您自己选择的流行库来创建一个 Jwt。然后它成为苹果 api 端点的client_secret参数。
4.最后,使用 上述流程中的参数调用撤销端点。
注意:我相信上面的解决方案是迄今为止最好的方法,假设您在服务器端保护密钥。除非您有办法扰乱密钥,否则您不应尝试将其存储在您的项目(或应用程序)中。