Get access token from Google login
Using version 1.2.5 and trying to upgrade existing Google login using a new mechanism.
Here is my HTML implementation
<asl-google-signin-button [type]="'standard'" [size]="'medium'" [text]="'signin_with'" [theme]="'outline'"></asl-google-signin-button>
and component.ts
ngOnInit() {
this.socialAuthService.authState.subscribe((user) => {
this.getAccessToken(); <--- Called to get access token
console.log('authState user: ', user); <--- Prints user email, name, full name, id, idToken, provider, photoUrl
console.log('Token from state: ', user.authToken) <--- Prints undefined
});
}
getAccessToken(): void {
this.socialAuthService.getAccessToken(GoogleLoginProvider.PROVIDER_ID).then(accessToken => {
console.log('access token: ', accessToken); <-- Does not print anything
});
}
The readme file reads
You are notified when user logs in or logs out. You receive a SocialUser object when the user logs in and a null when the user logs out. SocialUser object contains basic user information such as name, email, photo URL, etc.
along with the auth_token. You can communicate the auth_token to your server to authenticate the user in server and make API calls from server.
How can I get the access token to authenticate user in the backend as well?
You have the token inside the user object when you listen authState changes.
this.socialAuthService.authState.subscribe returns an user object.
- If
userequalsnull, your client is not logged (or just sign out !) - If
usernot empty, inside you will find a propertyidToken.
With idToken you can add in a HttpInterception a Bearer value.
Hope this comment will help you. See you 👋
@ruizalexandre I tried with the idToken but it does not seem to be a valid access token.
I had to add email, profile scopes, then get accessToken from the .getAccessToken() method.
@anuj-scanova I tried your workaround and it works fine, except that google asks the users to authenticate 2 times, once when clicking the button and once when calling .getAccessToken(). Do you have the same issue?
Why can't the AccessToken be provided in the property SocialUser::authToken instead of having to call a second method, just like the facebook API?
Thanks!
@MasterBroki Yes, in my case as well, Google asks for authentication twice.
@MasterBroki for me I get the JWT token on SocialUser.idToken, isn't that what your looking for?
@shyallegro We want the access_token which will be used from the backend to fetch user details using Google API and authenticate from the backend. In the previous version, the library was returning access_token.
I have the same issue, when calling the .getAccessToken() method a new login prompt is presented. So you have to click twice to get an access token for calling Googles' scoped apis. This is not very userfriendly.
I have checked the angularx-social-login code(working example https://stackblitz.com/edit/angularx-social-login-gc2ivh) and the difference is that in the old one there is addition of authToken
getLoginStatus(loginStatusOptions) {
const options = Object.assign(Object.assign({}, this.initOptions), loginStatusOptions);
return new Promise((resolve, reject) => {
if (this.auth2.isSignedIn.get()) {
const user = new SocialUser();
const profile = this.auth2.currentUser.get().getBasicProfile();
const authResponse = this.auth2.currentUser.get().getAuthResponse(true); // get complete authResponse object
this.setUserProfile(user, profile);
user.response = authResponse;
const resolveUser = authenticationResponse => {
user.authToken = authenticationResponse.access_token; // <--------- Addition of authToken
user.idToken = authenticationResponse.id_token;
resolve(user);
};
if (options.refreshToken) {
this.auth2.currentUser.get().reloadAuthResponse().then(resolveUser);
}
else {
resolveUser(authResponse);
}
}
else {
reject(`No user is currently logged in with ${GoogleLoginProvider.PROVIDER_ID}`);
}
});
}
which is not there in new version. Any major reason to remove this? I have the same problem with onetaplogin, even the popup showing again after login successfully.
When implementing what @anuj-scanova suggested, I'm receiving the access token intermittently. Sometimes it comes and sometimes it's undefined. Is there any solution or code snippet I can follow?
Also has any workaround been found to prevent the login prompt from coming twice?
I did not find a decent solution for this yet. At the moment I use this config:
GoogleInitOptions = { oneTapEnabled: true, prompt: ''}
With the onetap enabled and the prompt set to an empty string, the user is only prompted once when authenticating, the second time (when access token is requested) the popup is displayed only a second or so and then automatically continues.
But, the second popup is still visible for a while and the browser now also initially blocks the second popup. So still not something I would implement in production sites.
Guys, you can call https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=${idToken} with the idToken field to retrieve back end side user profile data.
This does not include the access toke however, the response:
{ "iss": "https://accounts.example.com/", "nbf": "##########", "aud": "##########", "sub": "##########", "hd": "demo.example.com", "email": "admin.##########@demo.example.com", "email_verified": "true", "azp": "##########", "name": "##########", "picture": "https://lh3.googleusercontent.com/a/##########=s96-c", "given_name": "##########", "family_name": "##########", "iat": "##########", "exp": "##########", "jti": "##########", "alg": "RS256", "kid": "##########", "typ": "JWT" }
Any news?
Can't get access token without another popup.
it seems here similar problem has been solved in the accepted answer:
https://stackoverflow.com/questions/72612704/how-to-get-oauth-token-after-google-one-tap-sign-in-jwt-token-response-of-one-t
just pushed some changes that makes things bit better. The code though is just minimum changes to test the idea from SO so would need to be properly reworked. Unfortunately do not have more time at this moment but maybe someone can make use of it/move it forward
with those changes no need to call getAccessToken(), just the user.authToken should already contain the access_token, also as per note on the PR, there is still popup showing for a moment (at leas in my case) but without user interaction needed
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
@anuj-scanova i am facing same issue that cannot get access token which i want to use backend api call.
Can you please help me how to get access token ?
@samarthkrtya We switched to another library https://github.com/i7N3/google-oauth-gsi and it is working great for us.
I had the same issue and came across this thread, wanted to share my solution as this still seems to be an missing as of 2.2.0.
@Component({
template: `<asl-google-signin-button type="standard" size="large"></asl-google-signin-button>`
})
MyComponent {
socialLogin$: Observable<SocialUser> = this.authService.authState.pipe(
concatMap((socialUser) =>
from(this.authService.getAccessToken(GoogleLoginProvider.PROVIDER_ID)).pipe(
map((authToken) => ({
...socialUser,
authToken,
}))
)
),
tap((socialUser) => {
console.log(socialUser.authToken);
// do any action you need.
})
);
}