-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FR: Calling an Apple Revoke Token endpoint #9906
Comments
A similar question has been asked on stack overflow. |
Hi @linkillhz - you can delete user accounts in Firebase Auth using if let user = Auth.auth().currentUser {
do {
try await user.delete()
}
catch {
print(error)
}
} See the docs for more details. To delete any of the user's associated data, you can use the Delete User Data Extension. This essentially is a Cloud Function that will run whenever a Firebase Auth user account is deleted (either using the call above or via the Firebase console), and can delete the user's data in Cloud Firestore, Cloud Storage, and the Realtime Database. If you find that your data model is different from what the Extension currently supports:
As for revoking the token, @rosalyntan and @renkelvin can provide more details. |
Hi, @rosalyntan and @renkelvin Firebase SDK did not call Apple's revoke token endpoint when I deleted my Firebase account.
Regards |
+1 Apple is complaining about this being a requirement June 30th. Looks like apps wont be accepted after that date if they do not delete tokens. This is the message:
|
+1 this is a real problem to be addressed before June 30. |
I don't think it makes sense to offer this with Firebase SDK. This is something the developer has to handle independently with apple auth. You can get the client secrets and token strings during login or sign up. It is decoupled from the Firebase flows. However, apple has provided very poor documentation for how to implement this. Even if you test their API with something like postman, you will always get status code 200 even with incorrect parameters. |
Perhaps you could help explain how this could be implemented, for clarity, I'm using Firebase & Flutter, I use Firebase Auth with flutter and sign_in_with_apple to authenticate with Firebase via the method in the documentation: https://firebase.google.com/docs/auth/flutter/federated-auth To delete my user, the documentation for firebase/flutter states to call This however would cause an app rejection via Apple's new policy. Is your position that users should know to create their own server outside Firebase, track secrets there after authenticating on Firebase, and then call that server to revoke tokens alongside the calls to firebase to delete the authenticated user? If so where should that be documented and would a cloud function and Firestore be fine to use to keep track of tokens and revoke on delete? |
Hi all - Thanks for raising this issue - we are aware of this and are actively working on a solution. We will update this issue once we can share more details. Documentation (and accompanying sample code) would definitely be part of the solution. This will likely be a blog post that shows how to use our solution, fast-followed by an update of our docs (https://firebase.google.com/docs/auth/ios/apple). We would want to avoid developers having to stand up their own servers outside of Firebase - this would defeat the whole purpose of an mBaaS platform. |
To @CalHoll, I would be delighted to know that the proposed solution being worked on by @peterfriese (and the Firebase team) could cover the upcoming requirement. However, you can see my attempt at this issue here: https://stackoverflow.com/questions/72399534/how-to-make-apple-sign-in-revoke-token-post-request/72488104?noredirect=1#comment128373667_72488104 The general principle of my approach is that I am attempting to perform a POST request with limited understanding of the parameters at play. I have not been able to verify that my solution works when running in a debug environment. To my understanding, I did not think it would have been possible to meet the requirement within the Firebase ecosystem, but will be very pleasantly surprised to be educated otherwise. |
Apple's revoke API is called based on JWT signed by the developer's key, so I think it will be difficult for the client to implement the function. I think it's most intuitive to upload a key file from the Firebase console (like cloud messaging) and automatically process it when user.delete(). However, with Apple's instruction request date just around the corner, the way to generate JWT and invoke API via Firebase functions seems not bad. |
Firebase functions require the Blaze plan, though. My app is small and so far I haven't used Firebase functions, yet. It would be great if we could just upload the JWT file to Firebase and Firebase takes care of the rest after calling delete() on the user account. |
For now I'm trying to implement the revocation calls myself, but I can't find a way to get |
Thanks for working on this Firebase team. I hope the fix and docs come out soon, as June 30 is right around the corner and no new app updates will be accepted without this implemented. |
I'm also trying to fill in the "token" parameter, |
Sadly this blog is not very helpful |
After getting the appleIDCredential.authorizationCode from the app, you need to get the refresh token through the auth/token API. The whole process is as follows.
I implemented it in Firebase functions and put the code to be reference on the link below. If you did it right, it would have disappeared from your device's Settings - Apps using Apple Sign-in. |
Thanks,it works!
Thanks!!!!! It works! |
Is there a general timeframe for when this will be implemented in the Firebase Auth flow? Curious if it is worth putting in the time for a custom solution or just wait for Firebase to implement this. |
@peterfriese Is there any expected solution within the coming days? |
From collective analysis on invertase/react-native-apple-authentication#282 it appears the only way to do the revoke is to generate a fresh valid authorization code + a fresh JWT built with a client secret that Firebase Auth has already It is possible to pre-generate and store a JWT locally (in app) with a maximum expiry of 6 months (per documentation) at cost of possible spoofing with exposed JWT plus need to update app periodically or you have a server API somewhere (could be here!) that can take the known secret firebase auth already has to generate the JWT for post to the Apple REST API for token revocation It does not appear there is any avoiding some user interaction though as I believe you need an authorization code from the Sign In With Apple APIs which is short-lived and based on my understanding of the Firebase Auth APIs, Firebase does not itself maintain a token to revoke? So if I understand correctly and all the above is correct - the optimization possible here is the elimination of the need for a server by use of some possible new firebase auth API and existing firebase servers, that can generate take a non-expired apple authorization code from a caller (perhaps react-native-apple-authentication, for react-native people) and do the rest (JWT generation, REST API calls). That's definitely useful so I'm interested in a timeline too if possible. As a library maintainer, it will take me a while to wrap anything that comes up for react-native-firebase and to communicate how to use it for react-native-apple-authentication users |
Hey @jooyoungho. |
@Knapiii You can implement a user-facing 'reauthentication' flow. That way you can require reauthentication prior to displaying the account deletion UI in your application. Doing that effectively requires that the user tap on another Sign In With Apple or Continue With Apple button. See https://firebase.google.com/docs/auth/ios/apple#reauthentication_and_account_linking for more details. Doing this safely guarantees you will have the sensitive information required to revoke the token without any of it expiring. Keep in mind, when reading the Firebase account deletion documentation, it can be considered a 'sensitive' action which would require reauthentication. Firebase recommends performing reauthentication for 'sensitive' actions. I think account deletion and revoking the token from Sign in With Apple are considered sensitive with regards to backend services. |
Please, Firebase (@peterfriese) , when you implement the solution, make it possible to revoke the Apple token of the user also from a web server, and not only from the app. I delete the user account from a web server (using this firebase php api https://github.com/kreait/firebase-php), because It does not force the user to re-authentify before account deletion. (I already display 2 confirmations popup in the app, to ensure that the user really wants to delete his account). |
Hi all, We are working on a long-term solution that will call Apple's REST API for token revocation when you delete a Firebase user account that was created using Sign in with Apple. In the meantime, we recommend choosing one of the following approaches:
Since Apple's Delete User Data requirements state that you should delete the user's data from your systems, we expect many of you will either implement their own Cloud Function for deleting the user's data from any Firebase services you use (such as Cloud Firestore, Realtime Database, or Cloud Storage), or use the Delete User Data Extension. In this case, we recommend choosing option 1 above. As mentioned, we are actively working on a long-term solution that should make the token revocation process a smooth experience. Once we have an implementation that we can share with you, we will update this GitHub issue. PS: please don't store any sensitive information in |
Yes, we're still on track for early Q1. We'll reach out to this thread once we've got something that you can take for a spin. |
Doesn't realy help with the JS SDK as I don't understand how to get the mentioned authorizationCode. I also created a Q&A Post here to get help: #10565 Do I understand it right that the early Q1 solution will not depend on any SDK but directly revoke Apple ID Logins when deleteing a firebase User connected to Apple ID? |
To revoke a token, you will have to call the let appleIDCredential = authorization.credential
let auth = Auth.auth()
do {
try await auth.revokeToken(appleIDCredential.authorizationCode)
} catch {
print("Token revocation failed with error \(error)")
} We considered making this a back-end only implementation, but this would require the Sign in with Apple access/refresh tokens/authorization code to be stored in our backend. We decided against this for a number of reasons:
You can follow #10580 for the implementation of the token revocation API. |
The revokeToken() could fail, so I assume it's meant to be called first and if it works successfully, then we delete the user's account? |
So it sounds like the Q1 solution will be something like:
If it's that easy.. and all done in my UI.. I'm definitely waiting until Q1! |
Hey guys, have there been any more updates on this? |
ditto |
If anyone is using Flutter and hung up on this, here is a temporary workaround. Delete user (App side)Since deletion is "security-sensitive operation", asking the user to log in again is recommended. I tried the Firebase Auth for providing the token and it did not work. I had to use Flutter CodedeleteUser() async {
final AuthorizationResult res =
await TheAppleSignIn.performRequests([
const AppleIdRequest(
requestedScopes: [Scope.email, Scope.fullName])
]);
switch (res.status) {
case AuthorizationStatus.authorized:
try {
// Get Token
final AppleIdCredential appleIdCredential = res.credential!;
String accessToken = String.fromCharCodes(
appleIdCredential.authorizationCode!);
try {
HttpsCallableResult resp = await FirebaseFunctions.instance
.httpsCallable('revokeToken')
.call(accessToken);
debugPrint(resp.data.toString());
if (resp.data["status"] != null) {
if (resp.data["status"].toString() == "success") {
await FirebaseAuth.instance.currentUser!.delete();
await signOut();
}
}
} catch (firebaseFunctionError) {
debugPrint(firebaseFunctionError.toString());
return firebaseFunctionError.toString();
}
} on PlatformException catch (error) {
debugPrint(error.message);
return error.code;
} on FirebaseAuthException catch (error) {
debugPrint(error.message);
return error.code;
}
case AuthorizationStatus.error:
return 'auth-error';
case AuthorizationStatus.cancelled:
return 'auth-cancelled';
default:
return 'auth-error-other';
}
} Revoke function (Server side)To revoke, use the authorization code obtained in the app to generate a Replace Firebase Functionexports.revokeToken = functions.https.onCall(async (request, response) => {
// import the module to use
const axios = require("axios");
const qs = require("qs");
const authorizationCode = request.toString();
const clientSecret = makeJWT();
let data = {
"code": authorizationCode,
"client_id": "com.example.app",
"client_secret": clientSecret,
"grant_type": "authorization_code",
};
// first get the refresh token
try {
const res = await axios.post("https://appleid.apple.com/auth/token", qs.stringify(data), {
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
});
const refreshToken = res.data.refresh_token;
data = {
"token": refreshToken,
"client_id": "com.example.app",
"client_secret": clientSecret,
"token_type_hint": "refresh_token",
};
// use the refresh token to revoke
try {
const res = await axios.post("https://appleid.apple.com/auth/revoke", qs.stringify(data), {
headers: {
"Content-Type": "application/x-www-form-urlencoded",
}});
functions.logger.log(res.status);
return {"status": "success"};
} catch (revokeError) {
functions.logger.log(revokeError);
return {"status": "failed", "message": revokeError.toString()};
}
} catch (refreshError) {
functions.logger.log(refreshError);
return {"status": "failed", "message": refreshError.toString()};
}
}); Note!This is just a proof-of-concept code. Do the appropriate error checks and take security measures as needed. |
Is it still in progress? |
Yes, it is. |
spent the last 2 days trying to get the cloud functions working just keep getting a 400 code from apple. Really hope this is fixed soon. |
For those who are running into 400 error: AuthorizationCode leaves only 5 minutes, and can be used only once. Otherwise, I'm getting 400 error. I haven't found this information anywhere except apple official documentation |
We are still looking for a practical solution to this problem. |
This will be launching in the next release of the Firebase SDK. |
Actually, my understanding is that this was fixed in #11001 and already released in 10.8.0. cc: @renkelvin |
@paulb777 Just to confirm, is the expected behaviour that calling Auth.auth().currentUser.delete { .. } should revoke the token automatically also? I tested this now so using 10.8.1, called delete but the token still appears in the apple id page. Could it be because the app isn't live on the app store? |
Hi @CristianMoisei - token revocation needs to triggered separately from deleting the user account. We're currently working on updating the docs (and a video is also on the way), but broadly speaking, you will have to do the following:
This works independently of whether your app is in the App Store or not. |
I try to understand Peter's recommendations, but do not understand how to get ASAuthorizationAppleIDCredential. We use flutter with firebase_auth. |
I've filed a feature request on the FlutterFire repo for you, @TheoBo |
Thank you @peterfriese, works great! I was wondering what would be best practice for handling token revocation while using the local Firebase emulator? When attempting to revoke the token with the Would simply skipping the above function be the way to go if the local emulator is being used? Thanks! |
@peterfriese sorry, but I imported |
It should be there: https://github.com/firebase/firebase-ios-sdk/blob/8efafcb340eb097f4faa2a3c24e46185ff28b28e/FirebaseAuth/Sources/Public/FirebaseAuth/FIRAuth.h#LL858C31-L858C31 - can you double check you're either on |
thank you, it's on the did you update |
CocoaPods and SPM use the same versioning. We release them at the same time. |
Feature proposal
Apple's new guidelines say,
If your app offers sign-in with Apple, you must use sign-in with the Apple REST API to revoke your user token when you delete your account.
https://developer.apple.com/news/?id=12m75xbj
Does Firebase Auth offer any functionality to assist with account deletion?
The text was updated successfully, but these errors were encountered: