How should I use the id token returned to me by Google after a successful code exchange?
I am not clear on what exactly I should do with the id token from Google after the initial verification.
I'm developing on expo/react native and get the id token locally. Then, I send it to my server and verify it using google client libraries. Once it's verified what should I do with it?
Ideally I could use it to protect my api routes (express) but id tokens expire after 1 hour and I'm not sure how to refresh them with the client library. So, I don't know how I would do this.
Is that the intended use for id tokens? Should I instead be signing my own jwt and sending that back to the client? Then, the client could send that in the auth header of each request to a protected routes.
Google says:
After you have verified the token, check if the user is already in your user database. If so, establish an authenticated session for the user. If the user isn't yet in your user database, create a new user record from the information in the ID token payload, and establish a session for the user. You can prompt the user for any additional profile information you require when you detect a newly created user in your app.
https://developers.google.com/identity/sign-in/ios/backend-auth
Do I use the id token to "establish a session for the user"?
2 answers
-
answered 2021-02-23 08:26
Tore Nestenius
Yes, the ID-token is only used to create the local session, perhaps also create a local entry in your local database if that is used.
The ID token also have a very short lifetime, like 5 minutes in some systems. So it has no long-term use.
-
answered 2021-02-23 09:01
Michal Trojanowski
The ID token is intended to authenticate the user. It gives you information about the authenticated user, it should not be used to allow access to your endpoints. Access tokens or sessions are intended to do so. So in your case, you should do exactly as your gut feeling tells you - create a session for the user basing on the data you got in the ID token.
If you have your own Authorization Server you can use the ID token to issue an access token and return the token to the frontend app, then use the access token to access your backends. Have a look at OAuth flows if you would want to go this way.
See also questions close to this topic
-
How to retrieve AccessToken in Auth0 for a specific user to deal with a permissioned REST API?
I am using Auth0 for User-Authentication in my VueJS-Application.
Now I want to create a backend providing a REST-API that will also use OAuth2-protocol and JWT-tokens in conjunction with our Auth0-based Frontend. This basically means: after SignUp of a new User, I want to send this new User to our backend in order to create a new record (which is already done).
The REST-API will be only accessible with a valid JWT-Token, which works perfectly following some tutorials and examples provided by Auth0 like this one.
I'd like to validate an access_token on my backend with Auth0 for a user, that was authenticated on the frontend application using auth0 also in the backend without sending any passwords.
This way, the Frontend or any other client can obtain an Access-Token like with this
curl
-command:curl --request POST \ --url https://dev-xxxxx.eu.auth0.com/oauth/token \ --header 'content-type: application/json' \ --data '{"client_id":"DLjQxxxx","client_secret":"*****","audience":"https://api.example.org","grant_type":"client_credentials"}'
On the backend, I am able to parse this token against Auth0 to check if this token is valid or not.
But how can I obtain a token on the Frontend for a specific user consisting of its email and password in Auth0-authentication? The Auth0-API will not return any access token after user authentication that I can use together with my API in order to validate the JWT token for specific roles.
I think I don't get the final workflow here.
Can someone point me please into the right direction?
-
error_description=attributes+required%3A+%5Bgender%2C+birthdate%5D&error=invalid_request
I'm developing an Android App and I'm trying to integrate Google Auth with AWS Cognito. So far I've succeeded in configuring Firebase but I'm having troubles mapping Google attributes to AWS Cognito ones. When I use AWS UI test I get the following error:
Here is how I mapped Google attributes to Cognito ones: google attributes mapping
Lastly, this is what I put when configuring Google as a Federation Identity provider in the Authorize Code form:
email profile openid https://www.googleapis.com/auth/user.gender.read https://www.googleapis.com/auth/user.birthday.read
So I do not understand with Cognito do not recognize gender and birthdate attribute even though I specified them. Thanks for your help
-
Response 400 for Fetch API call
I am trying to make a call using JavaScript's Fetch API to generate an OAuth Token but I keep receiving a 400 response code and I'm not sure why. I wrote the key and secret to the console to verify their values, and I made the same API call using cURL (with the response I expected). Is there a small issue in my syntax?
fetch('https://api.petfinder.com/v2/oauth2/token', { method: 'POST', body: 'grant_type=client_credentials&client_id=' + key + '&client_secret=' + secret }).then(r => { response = r.json() });
-
Google Logging API v2 Authentification troubles
I'm trying to authentificate by OAuth token but i didn't find the way to get it without Google prompt and url redirection.
I'm using php and google/apiclient:"^2.7" library
I try to get token with it but I didn't find the way to get it.
If it's not possible to perform it without a google prompt, how I can authenticate my request to the https://logging.googleapis.com/v2/entries:list?
Thanks in advance for your help.
I tried with the following method
public function init() { putenv('GOOGLE_APPLICATION_CREDENTIALS=' . $this->container->getParameter('service-account-authentification-file')); $scopes = [ 'https://www.googleapis.com/auth/cloud-platform', 'https://www.googleapis.com/auth/cloud-platform.read-only', 'https://www.googleapis.com/auth/logging.admin', 'https://www.googleapis.com/auth/logging.read', 'https://www.googleapis.com/auth/logging.write' ]; $middleware = ApplicationDefaultCredentials::getMiddleware($scopes); $stack = HandlerStack::create(); $stack->push($middleware); $client = new Client([ 'handler' => $stack, 'base_uri' => 'https://logging.googleapis.com/', 'auth' => 'google_auth' ]); $httpClient = $client->authorize(); $data = [ "resourceNames" => ["xxxx"], "filter" => "xxxxxx", ]; $response = $httpClient->post('https://logging.googleapis.com/v2/entries:list', [ 'body' => json_encode($data) ]); }
I also tried with this other method provided by the https://github.com/googleapis/google-cloud-php & https://github.com/googleapis/google-cloud-php-logging
$logging = new LoggingClient([ 'keyFilePath' => $this->container->getParameter('service-account-authentification-file') ] ); $entries = $logging->entries([ 'filter' => 'logName = projects/****logs/stdout' ]); foreach ($entries as $entry) { echo $entry->info()['textPayload'] . "\n"; }
Response is always the same
"error": { "code": 403, "message": "The caller does not have permission", "status": "PERMISSION_DENIED" }
I tried to use Curl
curl --request POST \ 'https://logging.googleapis.com/v2/entries:list?key=[YOUR_API_KEY]' \ --header 'Authorization: Bearer [YOUR_ACCESS_TOKEN]' \ --header 'Accept: application/json' \ --header 'Content-Type: application/json' \ --data '{}' \ --compressed
but i have such error too
{ "error": { "code": 400, "message": "The API Key and the authentication credential are from different projects.", "status": "INVALID_ARGUMENT", "details": [ { "@type": "type.googleapis.com/google.rpc.Help", "links": [ { "description": "Google developer console API key", "url": "https://console.developers.google.com/project/******/apiui/credential" } ] }, { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "reason": "CONSUMER_INVALID", "domain": "googleapis.com", "metadata": { "consumer": "projects/******", "service": "logging.googleapis.com" } } ] } }
-
Invalid Redirect: uses a forbidden domain, when Authorized redirect URI for Google Client ID Web App
CURRENTLY
I have a google apps script html page that incorporates Google Sign In
<!DOCTYPE html> <html> <head> <base target="_top" /> <script src="https://apis.google.com/js/platform.js" async defer></script> <meta name="google-signin-client_id" content="111222333444555666777888999.apps.googleusercontent.com"> </head> <body> . . .
This script successfully brings up the google sign in:
ISSUE
Clicking on the Sign in returns the following error message:
I then try to add the URI either to
Authorized Javascript Origins
orAuthorized Redirect URIs
, but get the following errorInvalid redirect: uses a forbidden domain
QUESTION
- Am I doing something obviously wrong?
- I note that another user who posted Google apps script oauth URI mismatch did not get
Invalid Redirect: uses a forbidden domain
error message when they added a similar URI. They wrote "I add https://n-z2mpomgsi6mxzkdegvwhypizz4zxupdihnp6udy-0lu-script.googleusercontent.com from my redirect uri mismatch error to the list of authorized javascript origin uris in the developer console because stackoverflow said so. This gets oauth working fine and dandy." Why is it they were able to do this, and I cannot?
-
Difference between signing with private key using oauth2client.service_account and google.oauth2
I'm attempting to update my function for signing urls for Google Cloud Storage to V4. Google provides a template for this and I think I follow it until this https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/storage/signed_urls/generate_signed_urls.py#L112
#signer.sign() signs using RSA-SHA256 with PKCS1v15 padding signature = binascii.hexlify( google_credentials.signer.sign(string_to_sign) ).decode()
I am currently using V2 and the oauth2client library. The code snippets for this currently are:
creds = ServiceAccountCredentials.from_json_keyfile_dict(service_account_creds) signature = binascii.hexlify(creds.sign_blob(string_to_sign)[1]).decode()
This doesn't seem to work however, as I am getting an error with the signature. I'm trying to reason about what's different between the two signing methods but I am having trouble. https://oauth2client.readthedocs.io/en/latest/_modules/oauth2client/service_account.html#ServiceAccountCredentials.sign_blob
There doesn't seem to be documentation in the RSA module in the docs for the google.oauth2 https://google-auth.readthedocs.io/en/latest/reference/google.auth.crypt.rsa.html
-
Azure AD Authentication - NextJS
I am trying to configure Azure AD authentication with NextJs. Required is to configure Authentication to retrieve OIDC bearer token similar to how it is done using React-OIDC.
The API external to NextJS, needs the Bearer Token to authorize. I could find next-auth AzureB2C authentication but it does not returns the Access-Token so that I can use to hit the API. [Also I feel it is not the same as AD Authentication]
I need help on this like how to get my app get authenticated (mostly on client side) to retrieve the access-token and get data from API.
Thanks.
-
Logout not working as expected Identityserver4
I am using identityserver4 for my web application. I am trying to redirect to the my MVC client, but it didn't work as expected.Currently it redirected as following
localhost:44396/Account/Login?logoutId=CfDJ8EJf06VwS5JNrKjxoskwu06e9wy1VhZ_t8NW7L8TBFsx9LBFSRBsm9aZImm_ZmK5GIRaaU_-0W5fktg-Nv88fwMuMnjsk1N-d4LzY1y8VSPHUlGJldUjBejAHkrVc-
I tried to fix the issue with this answer
Logout Method in MVC controller
public async Task Logout() { await HttpContext.SignOutAsync("Cookies"); await HttpContext.SignOutAsync("oidc"); }
Account Controller:
[HttpGet] public async Task<IActionResult> Logout(string logoutId) { var vm = await BuildLogoutViewModelAsync(logoutId); if (vm.ShowLogoutPrompt == false) { return await Logout(vm); } return View(vm); } [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Logout(LogoutInputModel model) { var vm = await BuildLoggedOutViewModelAsync(model.LogoutId); if (User?.Identity.IsAuthenticated == true) { // delete local authentication cookie await _signInManager.SignOutAsync(); await _events.RaiseAsync(new UserLogoutSuccessEvent(User.GetSubjectId(), User.GetDisplayName())); } if (vm.TriggerExternalSignout) { string url = Url.Action("Logout", new { logoutId = vm.LogoutId }); return SignOut(new AuthenticationProperties { RedirectUri = url }, vm.ExternalAuthenticationScheme); } if (vm.AutomaticRedirectAfterSignOut && !string.IsNullOrWhiteSpace(vm.PostLogoutRedirectUri)) return Redirect(vm.PostLogoutRedirectUri); return Redirect(vm.PostLogoutRedirectUri); }
How to solve this issue.
-
OidcClient : UWP WapBrowser.InvokeAsyncCore (BrowserOptions options, Boolean silentMode)
I try to use the Xamarin Forms to connect to identityserver using oidc client. I already configure the Xamarin Core and Xamarin Android works fine. The issue there is with UWP and the WapBrowser configuration to open the view and allows me to make authentication.
I did not change anything into the confifuration of the WabBrowser https://github.com/IdentityModel/IdentityModel.OidcClient.Samples/blob/main/XamarinForms/XamarinFormsClient/XamarinFormsClient.UWP/WabBrowser.cs . Unfortunately, I got the following error (HRESULT: 0x800C0005) ...UWP.WapBrowser.InvokeAsyncCore(BrowserOption options, Boolean silentMode)
The issue is that removing the silentMode will bring another issue, leaving it gives the above error.
What do I need to do to overcome this issue?
-
Android Firebase Google Login Failure delivering result error
I have been trying to resolve a bug for 3 days now and I can not find any solution anywhere.
I want to integrate Google Sign In via Firebase into my application, but something goes wrong with ActivityForResult I think. Here is my LoginActivity.java
import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; import android.util.Log; import android.widget.Button; import android.widget.Toast; import com.myapp.myapp.Classes.LoginWithProviderDialog; import com.myapp.myapp.Classes.GoogleSecureLoginDialog; import com.google.android.gms.auth.api.signin.GoogleSignIn; import com.google.android.gms.auth.api.signin.GoogleSignInAccount; import com.google.android.gms.auth.api.signin.GoogleSignInClient; import com.google.android.gms.auth.api.signin.GoogleSignInOptions; import com.google.android.gms.common.api.ApiException; import com.google.android.gms.tasks.Task; import com.google.firebase.auth.AuthCredential; import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.auth.GoogleAuthProvider; import com.google.firebase.firestore.DocumentReference; import com.google.firebase.firestore.FirebaseFirestore; import java.util.HashMap; import java.util.Map; import java.util.Objects; import br.com.simplepass.loadingbutton.customViews.CircularProgressButton; public class LoginActivity extends AppCompatActivity { private final static int RC_SIGN_IN = 1; private FirebaseAuth firebaseAuth; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); CircularProgressButton loginBtn = findViewById(R.id.loginBtn); loginBtn.setOnClickListener(v -> { loginBtn.startAnimation(); //TODO: Email sign in }); Button loginProvider = findViewById(R.id.loginProvider); loginProvider.setOnClickListener(v -> { LoginWithProviderDialog providerDialog = new LoginWithProviderDialog(LoginActivity.this); providerDialog.setProviderLoginListener(provider -> { if(provider.equals("Google")){ GoogleSecureLoginDialog googleSecureLogin = new GoogleSecureLoginDialog(LoginActivity.this); googleSecureLogin.setSecureLoginListener(status -> { if(status.equals(true)){ googleSignIn(); } }); googleSecureLogin.show(); } //TODO: Add more providers }); providerDialog.show(); }); } private void googleSignIn(){ firebaseAuth = FirebaseAuth.getInstance(); GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestIdToken("449022495080-o1ds6vadv5h311e5te4qhh7f643b4eap.apps.googleusercontent.com") .requestEmail() .build(); GoogleSignInClient signInClient = GoogleSignIn.getClient(LoginActivity.this, gso); Intent sign = signInClient.getSignInIntent(); startActivityForResult(sign, RC_SIGN_IN); } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == RC_SIGN_IN) { Task<GoogleSignInAccount> signInTask = GoogleSignIn.getSignedInAccountFromIntent(data); try { GoogleSignInAccount signInAcc = signInTask.getResult(ApiException.class); AuthCredential authCredential = GoogleAuthProvider.getCredential(signInAcc.getIdToken(), null); Toast.makeText(getApplicationContext(), "Hello, " + signInAcc.getDisplayName(), Toast.LENGTH_LONG).show(); firebaseAuth.signInWithCredential(authCredential).addOnCompleteListener(task -> { Toast.makeText(getApplicationContext(), "User registered to firebase with UID, " + firebaseAuth.getCurrentUser().getUid(), Toast.LENGTH_LONG).show(); }); String userID = Objects.requireNonNull(firebaseAuth.getCurrentUser()).getUid(); FirebaseFirestore firebaseFirestore = FirebaseFirestore.getInstance(); DocumentReference documentReference = firebaseFirestore.collection("users").document(userID); Map<String, Object> user = new HashMap<>(); user.put("name", signInAcc.getDisplayName()); user.put("email", signInAcc.getEmail()); documentReference.set(user).addOnSuccessListener(aVoid -> { SQLiteDatabase myappDB = openOrCreateDatabase("myappDB", MODE_PRIVATE, null); myappDB.execSQL("CREATE TABLE IF NOT EXISTS users(name VARCHAR, email VARCHAR, fuid VARCHAR, trackList INT);"); myappDB.execSQL("INSERT INTO users VALUES('" + signInAcc.getDisplayName() + "', '" + signInAcc.getEmail() + "', '" + Objects.requireNonNull(firebaseAuth.getCurrentUser()).getUid() + "', '" + "empty" + "');"); Intent intent = new Intent(LoginActivity.this, MusicActivity.class); startActivity(intent); }).addOnFailureListener(e -> { Toast.makeText(getApplicationContext(), "onFailure: " + e.toString(), Toast.LENGTH_LONG).show(); }); } catch (ApiException e) { e.printStackTrace(); } } } }
And this is the Logcat error I get:
2021-02-26 16:10:41.397 6985-6985/com.myapp.myapp E/AndroidRuntime: FATAL EXCEPTION: main Process: com.myapp.myapp, PID: 6985 java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=Intent { (has extras) }} to activity {com.myapp.myapp/com.myapp.myapp.LoginActivity}: java.lang.NullPointerException at android.app.ActivityThread.deliverResults(ActivityThread.java:5015) at android.app.ActivityThread.handleSendResult(ActivityThread.java:5056) at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:223) at android.app.ActivityThread.main(ActivityThread.java:7656) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) Caused by: java.lang.NullPointerException at java.util.Objects.requireNonNull(Objects.java:220) at com.myapp.myapp.LoginActivity.onActivityResult(LoginActivity.java:102) at android.app.Activity.dispatchActivityResult(Activity.java:8310) at android.app.ActivityThread.deliverResults(ActivityThread.java:5008) at android.app.ActivityThread.handleSendResult(ActivityThread.java:5056) at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:223) at android.app.ActivityThread.main(ActivityThread.java:7656) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) 2021-02-26 16:10:41.398 6985-7016/com.myapp.myapp I/FirebaseAuth: [FirebaseAuth:] Preparing to create service connection to fallback implementation
The documentation I read is here
-
Google OneTap Signup prompt not displayed in IOS chrome
We recenlty implemented the Google's OneTap signup feature in our web project.
It works fine in web and in android mobile browsers. But we were not getting the prompt in IOS Chrome.
As per the Google docs it should be covering IOS Chrome as well. https://developers.google.com/identity/one-tap/web/guides/supported-browsers
IOS chrome version we tried 87.0
Can someone help with this, Thanks in advance.
-
Trying to understand which SHA-1 (development and release) need to be added to firebase android project
I've recently started new android firebase project and added my debug SHA-1 key I generated in android studio. I grabbed config
.json
file and started working in the app. Particular are of interest for this was google sign in.Everything worked fine locally, so I created signed build (using signing keys managed by google play console and my upload key). I published build to internal testing. When I downloaded the app through play store, my google sign in was no longer working, so I assumed it is because I need to add SHA-1 for production / release build?
I added my
App signing key certificate
SHA-1 from google play console to firebase and downloaded new config json file. Now, google sign in doesn't work in debug nor in release and I am very confused.Which SHA-1 keys need to be added to firebase? I have
Debug
,App signing key certificate
(from google play console) andUpload key certificate
(from google play console) -
Failed To authenticate to specific firebase api project?
the project that I am trying to automate is This.
Manual Logged in
When I click on Google logged-in it will redirect to manual login. after I logged in successfully I can see there Post method
Request URL: https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyAssertion?key=AIzaSyDF-qMBES2pwjDAzWRRsu-FiAxZgJsBuIk Request Method: POST with the body requestUri: "FirebaseappURL" returnIdpCredential: true returnSecureToken: true sessionId: "SessionID???"
after that, it generates a Large respond
context: "" displayName. emailverified. expiresIn:3600 federatedId:... firstName:. fullName:. idToken: <Token> kind: "identitytoolkit#VerifyAssertionResponse" lastName: ... localId: <ID> oauthAccessToken: <Token> oauthExpireIn: 3600 oauthIdToken: <Token> photoUrl: <url> providerId: "google.com" rawUserInfo: <long json> refreshToken: <token>
I want to simulate it with post request with the postman after that, I will transfer it to Script
What I tried
Google API Config
I went to Google DashBoard Create Project.
Then I go to the OAuth consent screen and add my user as test users.
Add all the Clawee sites as authorizes.
Then I Went to Credentials and add Oauth 2.0 Client ID's of the Desktop client and got his ClientID and SecretID
Now from postman, I went to
https://accounts.google.com/o/oauth2/v2/auth?client_id=<ClientID>.apps.googleusercontent.com&response_type=code&scope=openid%20email&access_type=offline&redirect_uri=urn:ietf:wg:oauth:2.0:oob
I got my auth-code
now I send a request to
https://oauth2.googleapis.com/token
with params clientid,secretId,authCode,grant_type and get my Access Token + Refress Token
Now to check that, I navigate to https://www.googleapis.com/oauth2/v3/userinfo?access_token="
I got My User Info... It works
Now I tried to use that Access Token To login to Firebase app as they did but because I using my Own token and not a manual login I read about the "signInWithIdp" or "verifyCustomToken" And I tried with 'postBody': 'access_token=[My_Token]&providerId=google.com' or token: [My_Token]
Both Failed... What am I doing wrong?
-
How to request offline_access from Google using .AddOpenIdConnect() in ASP.NET Core?
I know Microsoft provides a Google-specific OIDC package (
Microsoft.AspNetCore.Authentication.Google
) which takes an option in.AddGoogle()
to specifyAccessType
that can be set tooffline
.But can this be done using the standard ASP.NET Core OIDC package
Microsoft.AspNetCore.Authentication.OpenIdConnect
and.AddOpenIdConnect()
?With Microsoft account we can simply request the
offline_access
scope and it works perfectly. But it does not work with Google and results in aninvalid_scope
error.