简体   繁体   中英

Unable to login with Google OAuth when deployed to Heroku

I am unable to login to the app when deployed to Heroku. I had a successful build and deployment, but when I launch the app it starts me logged out and upon attempting to login, it hangs and throws an Application error. Express/Passport/MongoDB + create-react-app

I chek my keys several time, everesting match perfect. On my localserver everesing working perfect. Can it be a problem with "https" response on server?

app link https://mysterious-thicket-20426.herokuapp.com/

git repo https://github.com/detoner777/email-feedback-app

heroku err logs:

2019-08-20T09:44:08.211815+00:00 heroku[router]: at=error code=H12 desc="Request timeout" method=GET path="/auth/google/callback?code=4%2FpAFASjHeS_JuqGKXbEIDY4Jh5zHBJZk-Zyg19q6DHWGVtuipmCKVt1hLpwKltJUHW9XB3EBLcPGorEQUI68uZCE&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile&authuser=0&session_state=330af188f3789437fd21ab099ebe776784cfe500..3fb5&prompt=none" host=mysterious-thicket-20426.herokuapp.com request_id=59b62556-d07c-42ae-8f7f-e89b3ab5b735 fwd="31.134.127.229" dyno=web.1 connect=1ms service=30000ms status=503 bytes=0 protocol=https 2019-08-20T09:52:03.838240+00:00 heroku[router]: at=info method=HEAD path="/" host=mysterious-thicket-20426.herokuapp.com request_id=81a31581-1aa6-478d-98af-68b6c479e32a fwd="217.182.175.162" dyno=web.1 connect=0ms service=1ms status=200 bytes=289 protocol=https

//inex.js
const express = require('express');
const mongoose = require('mongoose');
const cookieSession = require('cookie-session');
const passport = require('passport');
const bodyParser = require('body-parser');
const keys = require('./config/keys');
require('./models/User');
require('./services/passport');

mongoose.connect(keys.mongoURI);

const app = express();

app.use(bodyParser.json());
app.use(
    cookieSession({
        maxAge: 30 * 24 * 60 * 60 * 1000,
        keys: [keys.cookieKey]
    })
);


app.use(passport.initialize());
app.use(passport.session());

require('./routes/authRoutes')(app);
require('./routes/billingRoutes')(app);


if (process.env.NODE_ENV === 'production') {
    app.use(express.static('client/build'));
    const path = require('path');
    app.get('*', (req, res) => {
        res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'));
    });
}

const PORT = process.env.PORT || 5000;
app.listen(PORT);


// passport.js
const passport = require('passport');
const GoogleStrategy = require('passport-google-oauth20').Strategy;
const mongoose = require('mongoose');
const keys = require('../config/keys');

const User = mongoose.model('users');

passport.serializeUser((user, done) => {
    done(null, user.id);
});

passport.deserializeUser((id, done) => {
    User.findById(id).then(user => {
        done(null, user);
    });
});

passport.use(
    new GoogleStrategy(
        {
            clientID: keys.googleClientID,
            clientSecret: keys.googleClientSecret,
            callbackURL: '/auth/google/callback',
            proxy: true
        },
        async (accessToken, refreshToken, profile, done) => {
            const existingUser = await User.findOne({ googleId: profile.id });

            if (existingUser) {
                return done(null, existingUser);
            }

            const user = await User({ googleID: profile.id }).save()
            done(null, user);
        }
    )
);

Solved it, here's what worked for me:

Please check that your user/password for the Mongodb Atlas prod database correctly match the MONGO_URI variable that you set in Heroku, that was causing this issue for me. I think it's easy to make a typo here since you cannot see the password for the database user after you create it. Also note that the user should not be "read-only", and that this is not the same user/password combination that you use to log in to Mongodb Atlas.

I found that the reason why the authentication callback was failing with a timeout error was that the Google Strategy's callback defined in the file passport.js never called the method done(). This, in turn, happened because the query to find a user in the MongoDB never completed because Mongoose couldn't connect to the mlab.com database. I tried creating a new user for the prod database in mlab and updating that in the Heroku environment variables and it worked!

Try adding full url of server as callback url, check the documentation http://www.passportjs.org/docs/google/ , so your callback

URL will be https://mysterious-thicket-20426.herokuapp.com/auth/google/callback

Had the exact same problem as you with the same setup and everything.

I checked everything and noticed the my cluster on MongoDB had no activity and was paused. The cluster pauses when there are no connection made to it after a while. This meant the backend wasn't able to properly to the database, hence the timeout to /auth/google/callback .

Here's what happened:

After you've go through the OAuth credential on /auth/google page, google redirects you back to /auth/google/callback .

The route handler for /auth/google/callback endpoint picks up the request and uses the passport.authenticate('google') middleware (to verify the authentication)

Your passport.authenticate('google') middleware uses the Google Strategy and its configurations you've set up inside passport.js

Going back on the no connections made to your database issue, this means there will be an authentication problem within the Google Strategy. Specifically, in its callback function:

 async (accessToken, refreshToken, profile, done) => { const existingUser = await User.findOne({ googleId: profile.id }); if (existingUser) { return done(null, existingUser); } const user = await User({ googleID: profile.id }).save() done(null, user); }

Express app wasn't able to make a connection to the MongoDB earlier, and now it attempts to execute a promise: await User.findOne({ googleId: profile.id }) with no error handling . This means there should an unhandled promise rejection error appearing in your console and your app crashing down.

Like @Agasthian Rathinavel mentioned, do double check on your MongoDB credentials and the environmental variables so you're certain the backend is able to connect to the database.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM