londonappbrewery / Authentication-Secrets

Companion Code for the Authentication Module on The Complete 2019 Web Development Bootcamp
https://www.appbrewery.co
440 stars 524 forks source link

TypeError: OAuth2Strategy requires a clientID option #6

Open withrake opened 4 years ago

withrake commented 4 years ago

Hey there,

I tried to lift this project up on heroku, but it did not work. The app will crash, claiming the error 'TypeError: OAuth2Strategy requires a clientID option'. I have no idea what to do, since I followed every step, adjusted the ports and URLs. Do you have an idea?

Of course, I adjusted the .env file to my Google Credentials and I added the respective heroku URIs to the https://console.developers.google.com/apis/credentials/oauthclient/...

URI: https://HEROKU-NAME-XXXXX.herokuapp.com Redirect URI: https://HEROKU-NAME-XXXXX.herokuapp.com/auth/google/secrets

Here is the code so far:

//jshint esversion:6 require('dotenv').config(); const express = require("express"); const bodyParser = require("body-parser"); const ejs = require("ejs"); const mongoose = require("mongoose"); const session = require('express-session'); const passport = require("passport"); const passportLocalMongoose = require("passport-local-mongoose"); const GoogleStrategy = require('passport-google-oauth20').Strategy; const findOrCreate = require('mongoose-findorcreate');

const app = express();

app.use(express.static("public")); app.set('view engine', 'ejs'); app.use(bodyParser.urlencoded({ extended: true }));

app.use(session({ secret: "Our little secret.", resave: false, saveUninitialized: false }));

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

mongoose.connect("mongodb+srv://CHANGEDTHIS:ANDTHIS@MYACCOUNT-dfhed.mongodb.net/secretsDB", {useNewUrlParser: true}); //mongoDB Datenbank mongoose.set("useCreateIndex", true);

const userSchema = new mongoose.Schema ({ email: String, password: String, googleId: String, secret: String });

userSchema.plugin(passportLocalMongoose); userSchema.plugin(findOrCreate);

const User = new mongoose.model("User", userSchema);

passport.use(User.createStrategy());

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

passport.deserializeUser(function(id, done) { User.findById(id, function(err, user) { done(err, user); }); });

passport.use(new GoogleStrategy({ clientID: process.env.CLIENT_ID, clientSecret: process.env.CLIENT_SECRET, callbackURL: "https://HEROKU-NAME-XXXXX.herokuapp.com/auth/google/secrets", userProfileURL: "https://www.googleapis.com/oauth2/v3/userinfo" }, function(accessToken, refreshToken, profile, cb) { console.log(profile);

User.findOrCreate({ googleId: profile.id }, function (err, user) {
  return cb(err, user);
});

} ));

app.get("/", function(req, res){ res.render("home"); });

app.get("/auth/google", passport.authenticate('google', { scope: ["profile"] }) );

app.get("/auth/google/secrets", passport.authenticate('google', { failureRedirect: "/login" }), function(req, res) { // Successful authentication, redirect to secrets. res.redirect("/secrets"); });

app.get("/login", function(req, res){ res.render("login"); });

app.get("/register", function(req, res){ res.render("register"); });

app.get("/secrets", function(req, res){ User.find({"secret": {$ne: null}}, function(err, foundUsers){ if (err){ console.log(err); } else { if (foundUsers) { res.render("secrets", {usersWithSecrets: foundUsers}); } } }); });

app.get("/submit", function(req, res){ if (req.isAuthenticated()){ res.render("submit"); } else { res.redirect("/login"); } });

app.post("/submit", function(req, res){ const submittedSecret = req.body.secret;

//Once the user is authenticated and their session gets saved, their user details are saved to req.user. // console.log(req.user.id);

User.findById(req.user.id, function(err, foundUser){ if (err) { console.log(err); } else { if (foundUser) { foundUser.secret = submittedSecret; foundUser.save(function(){ res.redirect("/secrets"); }); } } }); });

app.get("/logout", function(req, res){ req.logout(); res.redirect("/"); });

app.post("/register", function(req, res){

User.register({username: req.body.username}, req.body.password, function(err, user){ if (err) { console.log(err); res.redirect("/register"); } else { passport.authenticate("local")(req, res, function(){ res.redirect("/secrets"); }); } });

});

app.post("/login", function(req, res){

const user = new User({ username: req.body.username, password: req.body.password });

req.login(user, function(err){ if (err) { console.log(err); } else { passport.authenticate("local")(req, res, function(){ res.redirect("/secrets"); }); } });

}); let port = process.env.PORT; if (port == null || port == "") { port = 3000; } app.listen(port, function() { console.log("Server has started successfully."); });

AnuragDwivedi98 commented 4 years ago

Be sure to npm install dotenv, and add require('dotenv').config(); to the top of your app.js file.

KOSIDOCS commented 4 years ago

Hey you have to add your dotenv parameters as it is to heroku dotenv eviromental options.

Check heroku environment variable options.

puneet-rihan commented 3 years ago

I struggled with this as well. Go to heroku and under your app settings for this app, reveal "config vars" and set them as CLIENT_ID and CLIENT_SECRET with respective values. That will fix it.