3

I have a React signs into Google using OAuth 2. I also have a node/express REST api that creates users. How do I authenticate the user using the data I receive when I login on the React app?

I've been trying to follow this: https://developers.google.com/identity/sign-in/web/backend-auth but the token I get from Google on login expires after an hour, so I can't use it to authenticate the user on the backend after that. So, how to I get a new token or a token that won't expire without logging in again?

I'm sure this is done on a million different websites across the internet, but I can't find any good documentation or guide on how.

asked May 25, 2017 at 17:50
2
  • Hi! I implement OAuth authorization long ago and i remember that trick was to set scope parameter to 'offline' so this will give your ability to generate new token from refresh token check this out developers.google.com/identity/protocols/… Commented May 25, 2017 at 18:28
  • I'm still very confused. Refreshing an access token needs a refresh token. Step 5 just returns a new id_token (not the refresh_token it says it does). And even if it did, refreshing an access token doesn't say it gives a new id_token. So I can get a new (from step 5) id_token, but only one, and that expires in an hour. So I'm still stuck. Commented May 25, 2017 at 23:30

2 Answers 2

1

First, use Passport to get accesstoken and refreshtoken. When the app got an error access token expired, you should get a new accesstoken using refresh token.

- Passport to get google oauth accesstoken and refreshtoken.

var passport = require( 'passport' )
var GoogleStrategy = require( 'passport-google-oauth2' ).Strategy;
var GOOGLE_CLIENT_ID = "xxxx"
 , GOOGLE_CLIENT_SECRET = "xxxx";
passport.use(new GoogleStrategy({
 clientID: GOOGLE_CLIENT_ID,
 clientSecret: GOOGLE_CLIENT_SECRET,
 callbackURL: "/auth/google/callback",
 passReqToCallback : true
 },
 function(request, accessToken, refreshToken, profile, done) {
 console.log('accessToken: ', accessToken);
 console.log('refreshToken: ', refreshToken); 
 }
));
app.get('/auth/google', passport.authenticate('google', { scope: [
 'https://www.googleapis.com/auth/plus.login'
 ], accessType: 'offline', prompt: 'consent'
}));
app.get( '/auth/google/callback', 
 passport.authenticate( 'google', { 
 successRedirect: '/',
 failureRedirect: '/login'
}));

- Get a new access token using refresh token

var requestREST = require('request');
requestREST.post('https://accounts.google.com/o/oauth2/token', {
 form: {
 grant_type:'refresh_token',
 refresh_token: refreshToken,
 client_id: GOOGLE_CLIENT_ID,
 client_secret:GOOGLE_CLIENT_SECRET
 }
 }, function (err, res, body) {
 console.log(body)
 });

Enjoy!

answered May 8, 2018 at 8:24
Sign up to request clarification or add additional context in comments.

4 Comments

I have a similar system on my back-end as well using passport-google-oauth. My issue is that what if I want to authenticate a client manually, with basic http requests (for example if the client doesn't allow spawning a new browser window or redirects). Is there a way to get the code parameter from the client itself and pass that to the callback in passport instead of having passport redirect you to google's login page.
If you want to access to developer specific resources, for example, google cloud bucket, you can get accessToken using REST api without user action. Read carefully official document and should create a correct JWT token.developers.google.com/identity/protocols/OAuth2ServiceAccount
If you want to access to developer specific resources, for example, google cloud bucket, you can get accessToken using REST api without user action. Read carefully official document and should create a correct JWT token.developers.google.com/identity/protocols/OAuth2ServiceAccount In google official document, it contains some errors. Host name should be accounts.google.com/o/oauth2/token instead of googleapis.com/oauth2/v4/token and "aud" param should also be accounts.google.com/o/oauth2/token
Here is curl. curl -X POST \ accounts.google.com/o/oauth2/token \ -H 'content-type: application/x-www-form-urlencoded' \ -d 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3......'
1

well, I think that you don't need to authenticate a user every hour via google sign in, instead authenticate it once and then use user auth token from your backend to keep him logged in app, just like you use it when we login user via login form.

answered Apr 3, 2023 at 2:43

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.