googleapis / google-auth-library-nodejs

🔑 Google Auth Library for Node.js
Apache License 2.0
1.71k stars 375 forks source link

please provide a working example of automatic token refresh #836

Closed bionicles closed 3 years ago

bionicles commented 4 years ago

Is your feature request related to a problem? Please describe. I want to make a react app talk to an Apollo GraphQL server but I'm frustrated with the google oauth2 setup process because there's no example ... it's unclear from a big picture perspective

the user clicks "Sign In" we get a code. We send the code to the server. Then what?

if the offline flow only returns a code, how do you get the user's email and name and id without making a request to your server?

Most of the examples use Express, with redirects, but GraphQL uses post, they're maintained by one random guy, they don't explain how to refresh the token / access user id on subsequent page views.

Describe the solution you'd like How do you make sure the user doesn't have to sign in over and over and over?

What happens on subsequent signins?

Does the user have to re-consent or do we have to send a different button?

Do you need to check if the user already consented and render different button settings?

How do you get the id_token if you're doing offline flow?

Should I just give up on google and switch to Github or Facebook login?

Is there a CLIENT AND SERVER full-stack example of how to set this up that is actively maintained by google?

Also, would it be possible to condense all the boilerplate?

I just want an official well maintained working example / developer guide for how to set up a react app and apollo graphql server so the user signs in ONE time and they don't have to re-sign-in hourly. Or, if offline flow is gonna be a huge mess, you guys should drop it, stop supporting it, and just simplify your docs so 50,000 devs don't waste multiple days trying and failing and trying and failing to set up single-sign-on with their react apps

Specifically, I want to:

  1. import a google sign in button react component (right now, we have to use one guy's react component instead of officially maintained google code ... ) on my React app
  2. when the user clicks it and consents to sign up for the app, I get the user's code to send to my graphql server, along with an id, name, and email.
  3. With the id_token and access code, I want to fire a graphql mutation to save the refresh code, in the database with the id ? (or access ?) token as authorization header.
  4. clarify what happens the N+1 infinity times the user revisits the site.

And I want it all to be published so other people don't have the same headaches I had

Describe alternatives you've considered I tried cognito but it's super not-secure. Auth0 is a middleman, I'd use facebook or github and I probably should, because I'm frustrated with Google Sign In right now It's relatively doable to just make the user click on the button every hour, but that's also terrible UX

I just want to set up google sign in with react and graphql without days of annoying guesswork, 100s of lines of boilerplate, reading 50 random dude's blogs, not knowing which of 50 different google documentation pages to use. Additional context https://www.apollographql.com/docs/apollo-server/security/authentication/ https://www.npmjs.com/package/react-google-login https://github.com/anthonyjgrove/react-google-login/issues/175# https://github.com/anthonyjgrove/react-google-login/pull/191 https://developers.google.com/identity/sign-in/web/server-side-flow (no nodejs server example, only java and python ... ?!) https://developers.google.com/identity/sign-in/web/reference#googleauthgrantofflineaccessoptions https://github.com/Shahzayb/mern-google-login/blob/master/controllers/auth.js

bionicles commented 4 years ago

https://developer.github.com/apps/building-oauth-apps/authorizing-oauth-apps/ https://developers.facebook.com/docs/facebook-login/ https://developer.twitter.com/en/docs/basics/authentication/overview/3-legged-oauth

bionicles commented 4 years ago

edited. sorry for long post. just want to get auth right. thanks in advance for any help

bcoe commented 4 years ago

@bionicles are you trying to make authenticated requests to Google APIs, or are you just trying to use Google as an OAuth provider for your application?

For authentication, I think reading up on OIDC would be a good start:

https://developers.google.com/identity/protocols/OpenIDConnect

:point_up: my hunch is that that document is more suited towards your use-case; this library helps make authenticated requests against google APIs, e.g., drive, cloudbuild, etc.

bionicles commented 4 years ago

yes and I have read this and am familiar with it,, and at the top of that link it sends you here: https://developers.google.com/identity/sign-in/web/backend-auth which shows clearly this 'google-auth-library-nodejs' git repo as the solution to verify the identity on the server-side.

if you guys have N different "google auth nodejs" libraries, then, why?

the current solution has at least these issues:

  1. you have to add a script tag to your html and cannot add and import an npm package into react for the sign in button. we want to yarn add google-signin ... sucks devs into google conditional callback hell just to load and initialize auth instance on the client side and frequently crashes the app if you use the code from the site you just linked. This is spaghetti boilerplate with tons of opportunity to screw up:

    useEffect(() => {
    if (authInstance) {
      console.log("authInstance exists");
      return;
    }
    if (!window.gapi) {
      console.log("no window.gapi");
      return;
    }
    window.gapi.load("client:auth2", () =>
      window.gapi.client.init({ clientId, scope }).then(initResponse => {
        window.gapi.auth2.getAuthInstance().then(authInstance => {
          console.log("authInstance", authInstance);
          dispatch(["SET", { authInstance }]);
          console.log("auth2 object:", window.gapi.auth2);
          const googler = authInstance.currentUser.get();
          console.log("googler", googler);
          const basicProfile = googler.getBasicProfile();
          console.log("basicProfile", basicProfile);
        });
      })
    );
    });
  2. every user has to context-switch and click twice every hour to re-login as access token times out and id verification stops working. there's no example of how to refresh the google sign-in token on the docs; if you follow the current guide, you write callback-boilerplate but users must re-sign with google over and over and over. “SignIn” method only lasts 1 hr ... so the api docs indicate we need offline access consent, but only works once...and doesn’t return identity, just a code, so we have to write a bunch more boilerplate (with no docs) to send a code to our server, then server must get tokens, we store an access token in localstorage and refresh the token in our graphql server every hour? Oh, AND we need to add a bunch of ternary operators to our button needs a conditional to do a different thing if the user is signed in. Wtf, all I wanted is a sign in button, not a Mars Rover.

Why call it “Google Sign In” if it’s gonna be “Google callback hell request offline access send code get token save token return token store token refresh token”

And we’re supposed to figure it out with no documentation ^_^ no thanks man, this signin auth stack doesn’t meet the level of quality people expect from google

Why doesn’t sign in just work ... right now it’s not documented AND broken. Not fun if you just want to let your users click a button, and it’s easier to deploy a huge backend with a Terraform and Ansible and Kubernetes than to figure out how to refresh tokens with Google Sign In. “Not my problem, not my repo” ... sorry to be rude but this is literally waste of developer’s lives, and it;s sad

Silos r bad. Switching to SMS Auth with Twilio, can’t afford bad docs

renanlecaro commented 4 years ago

I'm also frustrated by the lack of examples in how to handle the token refresh workflow. My app ends up re-prompting users all the time because the refresh fails very often. I know i'm the one that didn't code it right, but as this is my first implementation of an OAuth2 flow, i'd love more documentation on the token refresh process

bcoe commented 4 years ago

we will make an effort to add docs that demonstrate the refresh token flow 👍

fhinkel commented 3 years ago

Greetings, we're closing this due to inactivity. Please let us know if the issue needs to be reopened.