簡體   English   中英

在 Heroku 上實時部署時,passport google oauth2 會導致“內部服務器錯誤”

[英]passport google oauth2 causes “internal server error” when deployed live on Heroku

我通過 mongoose 連接到 mongoDB 並且在本地主機上使用我的應用程序時沒有錯誤,但是當我將它部署到 Heroku 時,我收到了內部服務器錯誤。

這是我的js代碼:

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.use(bodyParser.urlencoded({extended: true}));
app.set("view engine", "ejs");

app.use(session({
  secret: varkey,
  resave: false,
  saveUninitialized: false
}));

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

mongoose.connect("mongodb+srv://admin-name:password@cluster0-7monv.mongodb.net/userDB?retryWrites=true&w=majority", {useNewUrlParser: true, useUnifiedTopology: true});
mongoose.set("useCreateIndex", true);

const userSchema = new mongoose.Schema({
  email: String,
  password: String,
  googleId: 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.GOOGLE_CLIENT_ID,
  clientSecret: process.env.GOOGLE_CLIENT_SECRET,
  callbackURL: "https://herokudomain.herokuapp.com/auth/google/callback",
},
  function(accessToken, refreshToken, profile, cb) {
    User.findOrCreate({ googleId: profile.id }, function (err, user) {
      return cb(err, user);
    });
  }
));

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

app.get("/auth/google/callback",
  passport.authenticate("google", { failureRedirect: "/login" }),
  function(req, res) {

    res.redirect("/");
});

這些是我的 html 代碼:

<a class="btn" href="/auth/google" role="button">Sign Up with Google</a>

Heroku 日志在他們的錯誤日志中顯示了這一點:

2020-06-09T04:05:10.523711+00:00 app[web.1]: MongoError: E11000 duplicate key error collection: userDB.users index: username_1 dup key: { username: null }
2020-06-09T04:05:10.523722+00:00 app[web.1]:     at Function.create (/app/node_modules/mongodb/lib/core/error.js:51:12)
2020-06-09T04:05:10.523722+00:00 app[web.1]:     at toError (/app/node_modules/mongodb/lib/utils.js:149:22)
2020-06-09T04:05:10.523723+00:00 app[web.1]:     at /app/node_modules/mongodb/lib/operations/common_functions.js:265:39
2020-06-09T04:05:10.523723+00:00 app[web.1]:     at handler (/app/node_modules/mongodb/lib/core/sdam/topology.js:913:24)
2020-06-09T04:05:10.523724+00:00 app[web.1]:     at /app/node_modules/mongodb/lib/cmap/connection_pool.js:356:13
2020-06-09T04:05:10.523724+00:00 app[web.1]:     at handleOperationResult (/app/node_modules/mongodb/lib/core/sdam/server.js:489:5)
2020-06-09T04:05:10.523725+00:00 app[web.1]:     at MessageStream.messageHandler (/app/node_modules/mongodb/lib/cmap/connection.js:270:5)
2020-06-09T04:05:10.523726+00:00 app[web.1]:     at MessageStream.emit (events.js:315:20)
2020-06-09T04:05:10.523726+00:00 app[web.1]:     at processIncomingData (/app/node_modules/mongodb/lib/cmap/message_stream.js:144:12)
2020-06-09T04:05:10.523726+00:00 app[web.1]:     at MessageStream._write (/app/node_modules/mongodb/lib/cmap/message_stream.js:42:5)
2020-06-09T04:05:10.523727+00:00 app[web.1]:     at writeOrBuffer (_stream_writable.js:352:12)
2020-06-09T04:05:10.523727+00:00 app[web.1]:     at MessageStream.Writable.write (_stream_writable.js:303:10)
2020-06-09T04:05:10.523728+00:00 app[web.1]:     at TLSSocket.ondata (_stream_readable.js:712:22)
2020-06-09T04:05:10.523728+00:00 app[web.1]:     at TLSSocket.emit (events.js:315:20)
2020-06-09T04:05:10.523729+00:00 app[web.1]:     at addChunk (_stream_readable.js:302:12)
2020-06-09T04:05:10.523729+00:00 app[web.1]:     at readableAddChunk (_stream_readable.js:278:9)

而 web 應用程序返回“內部服務器錯誤”頁面。 似乎他們在說我的數據庫有重復,但我已經清除了我的數據庫並且那里沒有任何內容了。

請幫助我,我對編程很陌生,所以我仍在學習如何閱讀錯誤代碼並理解它們,以便我自己調試。

我已經看到了類似的問題並嘗試了提供的解決方案,但它們都不適用於我的情況,這就是我決定提出這個問題的原因。

為什么你有錯誤:

從錯誤日志中:

2020-06-09T04:05:10.523711+00:00 app[web.1]: MongoError: E11000 duplicate key error collection: userDB.users index: username_1 dup key: { username: null }
...

我可以推斷您在users集合中的username名字段上有一個唯一索引,並且因為您有一個username名字段為空(null)的現有文檔,MongoDB 阻止您插入另一個username值為空的文檔。

從您發布的代碼中,我可以看到 User 架構不包含username段,也許您以前曾經在架構中擁有它。 您應該注意,根據您清除數據庫中數據的方式,索引可能會或可能不會被清除,在這種情況下, username名字段上的索引沒有被清除。

修復:

刪除username屬性上的索引。 在 mongo CLI 中運行db.users.dropIndex("username_1")來做到這一點。 您可以在之后運行db.users.getIndexes()以確保索引只存在於您需要的地方。

由於根據 MongoDB 它認為用戶名是唯一的,因此不會讓 null 值第二次進入數據庫。 當您從谷歌獲取個人資料時,您需要發送用戶名。 我的代碼如下

    (accessToken, refreshToken, profile, cb) => {
        console.log(profile);
        //install and require find or create to make following function work
        User.findOrCreate({
            googleId: profile.id,
            username: profile.emails[0].value
        }, (err, user) => {
            return cb(err, user);
        });
    }
));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM