Home > database >  Google Login fails: either I get an error about an unlisted "redirect_uri" value or I get
Google Login fails: either I get an error about an unlisted "redirect_uri" value or I get

Time:02-06

I am trying to enable users to log into my page using Google Social Sign On.

This worked in development and now I am going to production with it. It is a resume project.

To start the login process I click an anchor tag which redirects me to https://www.example.com/api/auth/google which Nginx sends to my backend endpoint: this.router.get("/google", googleAuth); which performs some magic to redirect the user to a page that formerly showed my 3 Google accounts.

This page fails and says "Access blocked: This app’s request is invalid"

enter image description here

I click to see error details and get

Error 400: redirect_uri_mismatch

You can't sign in to this app because it doesn't comply with Google's OAuth 2.0 policy.

If you're the app developer, register the redirect URI in the Google Cloud Console.
Request details: redirect_uri=http://localhost:8000/auth/google/callback

I am expecting it to redirect to https://www.example.com/api/auth/google/callback

In my Google console for this application I click under OAuth 2.0 Client IDs and see that my "Authorized redirect URIs" lists one singular entry where I expect to look and see "http://localhost:8000/auth/google/callback" : but it says https://www.example.com/api/auth/google/callback

It's like OK why not add the localhost:8000 value to the redirect URIs? Ok let's try it

enter image description here

Now I try clicking the Google button, and get redirected to a list of my available google accounts as I want. But now when I click one of them to be logged in, I get redirected to localhost, which is not what I want, I want my production URL:

This site can’t be reached

localhost refused to connect.

So what I want is for the redirect to the login page to come from my "example.com/api/auth/google" URL, and for the redirect to be sent to "example.com.api/auth/google/callback"

How can I make this happen? I think it requires nginx configured somehow.

edit to include code:

Here are the relevant controller endpoints

this.router.get("/google", googleAuth);
this.router.get("/google/callback", googleAuthCallback, this.grantAccessToken.bind(this));

googleAuth and googleAuthCallback:

export const googleAuth = passport.authenticate("google", { scope: ["email", "profile"], successRedirect: "http://localhost:3000" });

export const googleAuthCallback = passport.authenticate("google", { session: false });

My client side code that starts the redirect:


const GoogleButton: React.FC<{}> = () => {
    const startGoogleSignInFlow = getEndpoint("/auth/google");
// the value is https://www.apartmentsneargyms.com/api/auth/google 
    return (
        <a href={startGoogleSignInFlow} className="flex items-center">
            <div className="w-full h-12 flex justify-center rounded-lg googleBtn">
                <button className="flex items-center mr-4">
                    <img alt="google icon" src={GoogleIcon} height={24} width={24} className="mr-2" />
                    Google
                </button>
            </div>
        </a>
    );
};

I almost exclusively followed this guide to get here.

My nginx configuration proxies www.example.com/api to the backend server like this:

location /api/ {
       proxy_pass http://localhost:8000/; 
}

I'm suspicious the problem is that the Google services are hearing from me in the form of a request that starts with localhost:8000 because the redirects come from that location on my remote machine's network.

edit2: I want to say that I had this working on my local machine using localhost. It's deploying to prod that's difficult here.

CodePudding user response:

On the following line:

export const googleAuth = passport.authenticate("google", { scope: ["email", "profile"], successRedirect: "http://localhost:3000" });

You've your local env URL hardcoded (http://localhost:3000), this value must be different in dev and production.

CodePudding user response:

Found the source of the problem. Linda Lawton - DaImTo was right to tell me to post my code. I found this in my passport config:

const passportConfig = (passport: any) => {
    passport.use(
        new GoogleStrategy(
            {
                clientID: googleClientId,
                clientSecret: googleClientSecret,
                callbackURL: "http://localhost:8000/auth/google/callback",
                passReqToCallback: true,
            },
    // snip
}

  • Related