We had logged our users who cannot receive tokens and got this error:
Error=INVALID_PARAMETERS'. It is missing 'token' field." UserInfo={NSLocalizedFailureReason=Invalid registration response :'Error=INVALID_PARAMETERS'. It is missing 'token' field. That's because of we're missing FCM token. How can we ensure that each and every user gets FCM token for sure?
We did write up to date code according to tutorial.
Related
Validating the firebase id token in ruby on rails with library "firebase_id_token".
Once I got the valid token from the front-end with the google_sign_in library and sending it to the backend, it always prompts as "JWT::VerificationError (Signature verification raised)". Even though I have checked in jwt.io, where I could able see the information of payload and header but unable to verfiy the signature.
firebase_id_token.rb
FirebaseIdToken.configure do |config|
config.project_ids = ["project_id"]
config.redis = Redis.new(host: "localhost", port: 6379)
end
FirebaseIdToken::Certificates.request
Also, I checked the kid key is a valid one on this link
https://www.googleapis.com/robot/v1/metadata/x509/securetoken#system.gserviceaccount.com
I have been debugging the code for more than a week, Please anyone assist with this issue.
PS: I have tested the code with a valid token and not an expired one.
Google sign-in returns an OAuth2 token, not a JWT as far as I know, and definitely not a Firebase ID token. If you are passing this Google sign-in token to your backend code, it correctly gets rejected when you try to verify it as a Firebase ID token.
To get a Firebase ID token, you need to sign-in to Firebase with the Google sign-in token (by calling signInWithCredential) and then pass the resulting Firebase ID token to your backend code.
I'm using the AppleAuth npm package in my server to submit token requests to Apple's servers during the sign in with Apple process. (This is based off the sample server code provided with the sign_in_with_apple package in pub.dev) I have no issues submitting the authorization code to get my first access and refresh tokens.
However, when trying to test how my app would get a new refresh token, when I submit a POST request to https://appleid.apple.com/auth/token with the grant_type set to refresh_token the response I get is different than from having the grant_type set to authorization_code.
I looked at the source code of the package, and for its AppleAuth(myConfig).refreshToken(myRefreshToken) (<- pseudo code lol) the only difference in the POST payload is:
{
grant_type: 'refresh_token', // instead of grant_type: 'authorization_code'
refresh_token: refreshToken, // instead of code: authorizationCode
... // other params
}
While the initial request with authorization code returns both an access token and a refresh token, for some reason the refresh token request is only returning the access token. I really don't think it's the package causing the error, nor can I see how my code would be the source either, since the above code is the only difference.
I tried passing the access token that it returns in a new refresh token request in order to test that I can get new refresh tokens whenever necessary in the future, but it returns a 400 status error.
Am I missing something here? Is there a reason the refresh token request returns no new refresh token? Or am I missing something entirely about how the process/flow is supposed to work? I am trying to do this for the "check the refresh token once daily to confirm the user is still in good standing with Apple's servers" part of the process.
I've really been stuck on what to do at this point. I can save the identity_token.sub field in my database to check whether my user is signed in, but of course I want to make sure my user's apple ID is still valid with apple, and that they haven't revoked access. Could it be that because I tried to get a new refresh_token too soon Apple only returned the access_token?
Oh also, the app itself is a Flutter app and I am testing all of this on my iPhone 11 so it's not an Android/Web flow.
Whether you get a new 'rolling / rotating' refresh token in a refresh token grant response is generally vendor specific:
You may get a new refresh token occasionally but not always
The primary purpose of this message is to get a new access token, not a new refresh token
In terms of token handling, the client should update its tokens similarly to the saveTokens method in this sample of mine.
I've not used Sign In with Apple but I suspect proceeding as follows would be the simplest solution:
Keep access tokens short lived: no more than 60 minutes
This forces a frequent token refresh, which by default is very quick
If the user's Apple Id is revoked I would expect this to return an invalid_grant response
I got the temporary access token, serverAuthCode, web client id and its secret, i am trying to get refresh token from oathplayground but i am getting invalid grant error. I have rechecked the tokens many times but still getting same error. Here are the screenshots :
What can i do to get the refresh tokens ? For more information, i am using react-native-google-sign-in library, from this library, i got the 1. access_token, ServerAuthCode. From Google Developers console, i got the 1.Web Client Id 2.Client Secret , I am using these credentials inside the react native app and i am getting the tokens successfully, but the problem is sometimes they work and most of the times i get "invalid credentials" error when i try to use the access token, it is because the access token is expired, that's why i need the refresh token. If you have any idea why i am not able to get refresh token or how to get refresh token using another method, please let me know.
I understood what i was doing wrong, i was using the serverAuthCode that was not new, it should be the latest one + the first time when you allowed the app for permissions, and it will work only first time, after you have exchanged it for a refresh token, it will not work again and will always give you grant_error. So after getting the refresh token you can get a new refreshed access token. I was using react-native-google-sign-in and was in need of refreshed token, read below to know more about the same.
For React-native-google-sign-in :
The access token you will receive from GoogleSignin.getTokens(); will only last for about an hour, to get a new access_token we need to send serverAuthCode to https://oauth2.googleapis.com/token with fields : client_id, client_secret, code(this is serverAuthCode), grant_type(its value should be authorization_code), redirect_uri(can set it from developers console). Remember to only use the serverAuthCode that you get on your first attempt when you just allowed your app for the permissions FIRST TIME otherwise you will get grant_error every time. After getting the refresh_token, we need to get the new access_token using refresh token that we just got, so now just replace the value of grant_type from authorization_code to refresh_token and also replace the value of code field to refresh_token , fill its value and send a post request to the same url, you will get a fresh access_tokenthat will be valid for 1 hour.
Once a user's token expires (either because of the expiration date or because the app was removed from the FB apps list) any graph request generates an error (in my case error 190) because of the invalid token.
If the user tries to log in again I get a new token but that token does not get stored in the parse User table. For the login I use:
PFFacebookUtils.logInInBackground(withReadPermissions: permissions) {(returnedUser, error) in
I'm expecting Parse SDK to update the AuthData entry for that user with the new token and expiration date but that's not happening. Any idea why is that?
I am getting the FCM first time and save it to my userDefaults. Now When user logs out, how can I refresh the FCM token again? I have searched the docs and many other asked questions, but didn't find a better solution.
Thanks in advance.
The FCM Token is an Instance ID token, it represents the installed app and not the signed in user. Generally once the app remains installed it will have the same token no matter what user is signed in.
You would have to manage what user is associated to the token yourself. When the user signs in you should associate the token with the user's ID and when the user signs out you should remove that association.
To get a new refreshed FCM token (forcefully), first you have to delete it and then request for FCM token again. It will always provide a new token after once deletion.
To delete a saved token:
FirebaseMessaging.getInstance().deleteToken()
To request a FCM token:
Firebase.messaging.isAutoInitEnabled = true
// Get token
FirebaseMessaging.getInstance().token.addOnCompleteListener(OnCompleteListener { task ->
//On token fetch fail
if (!task.isSuccessful) {
//msg_token_failed
Log.e("Token failed", task.exception)
return#OnCompleteListener
}
// Get new Instance ID token
val newDeviceToken = task.result
Log.e("newDeviceToken", newDeviceToken)
})
So, in your case you can delete FCM token on logout and request it again on login. It will work.
Check this post:
Firebase Cloud Messaging - Handling logout
Mentioned security issue in #Arthur's comment is solved!