我对以下情况有点困惑 . 我正在使用带有google auth的护照JS登录我的网站 . 之后我尝试确保登录后的路线,它总是返回true .

我知道这是很多代码,我要求有很多时间来检查这个,但我真的在这里失去了我想我错过了一些非常明显的东西:(

谢谢你的时间!

这是相关的代码服务器 index.js 代码 . 在我看来,没有什么不寻常的

const env = process.env.NODE_ENV || 'development';
import dotenv from 'dotenv';
if (env === 'development') dotenv.config();

import express from 'express';
import bodyParser from 'body-parser';
import compression from 'compression';
import cookieParser from 'cookie-parser';
import methodOverride from 'method-override';

// IMPORT AUTH DEFAULT FUNCTION, THIS DEFINES THE STRATEGY
import auth from './middleware/auth';

import routes from './routes';
import database from './database';
import models from './models';

const PORT = process.env.PORT || 3000,
      app  = express(),
      router = express.Router(),
      sequelize = database();

app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
app.use(compression());
app.use(cookieParser());
app.use(methodOverride());

models(sequelize).then(models => {
  // CALL AUTH DEFAULT FUNCTION, THIS SHOULD SET WHOLE STORY IN MOTION
  auth(app);
  routes(app);
  app.listen(PORT);
});

这是我的路由文件,我宣布路由器,并在最后说应用程序应该使用它,我实际上怀疑这可能是问题,但不知道如何正确测试这个(除非我抛弃路由器,只是使用 app.use 而不是 router.use

import express from 'express';
import path from 'path';
import serveStatic from 'serve-static';

// IMPORT JUST THE ensureAuthenticated MIDDLEWARE
import {ensureAuthenticated} from '../middleware/auth';
import * as tasks from './tasks';

const router = express.Router(),
      root   = path.join(__dirname, '..');

export default function (app) {
  const frontendPublicPath = path.join(root, '..', 'frontend', 'build');

  router.use('/', serveStatic(frontendPublicPath));

  // TRY TO LOCK THIS ROUTE BEHIND AUTH
  router.use('/admin/dosomething', ensureAuthenticated, task.doSomething);

  router.use('*', serveStatic(frontendPublicPath));
  app.use('/', router);
};

最后这里是auth文件,它设置了所有内容

import passport from 'passport';
import expressSession from 'express-session';
import connectPgSimple from 'connect-pg-simple';
import googleAuth from 'passport-google-oauth';

import {models} from '../models/index';

const googleStrategy = googleAuth.OAuth2Strategy;

function setupPassport() {
  passport.serializeUser((user, done) => {done(null, user);});
  passport.deserializeUser((obj, done) => {done(null, obj);});

  passport.use(new googleStrategy({ clientID: process.env.GOOGLE_CLIENT_ID, clientSecret: process.env.GOOGLE_CLIENT_SECRET, callbackURL:  process.env.GOOGLE_CALLBACK_URL
    }, function (accessToken, refreshToken, profile, done) {
      process.nextTick(() => {
        models.Users.login(profile).then((userRecord) => {
          if (!userRecord.err) return done(null, userRecord);
          else return done(userRecord.err, null);
        });
      });
    }
  ));
}


/* Should be able to use this on whole app level if wanted, in that case
   allowedGuestRoutes would kick in to allow certain routes always to pass
   In example: app.use(ensureAuthenticated) !! NOT USED IN THIS CASE

   Also can be used on single routes by passing it as middleware
   In example: router.use('/admin/dosomething', 
                          ensureAuthenticated, 
                          task.doSomething);

   'root' route  - should be able to access route to get homepage served
   'dist' folder - should be able to access css / js and assets
   'auth' routes - should be able to access route to be able to login */

export function ensureAuthenticated(req, res, next) {
  const allowedGuestRoutes = ['/auth/','/api/'];
  if (req.isAuthenticated()) {
    // I ALWAYS END UP HERE SINCE THIS IF CASE IS ALWAYS TRUE <-----------
    return next();
  } else {
    /* Don't reject, check if this route is public */
    let publicRoute = false;
    if (req.url === '/') {
      publicRoute = true;
      return next();
    }
    allowedGuestRoutes.forEach(guestRoute => {
      if (req.url.indexOf(guestRoute) === 0) {
        publicRoute = true;
        return next();
      }
    });
    if (!publicRoute) {
      logger.error(req, 'Not allowed to access route');
      res.redirect('/');
    }
  }
}

export default function (app) {
  const pgSession       = connectPgSimple(expressSession),
        cookieAge       = 7 * 24 * 60 * 60 * 1000,
        sessionSettings = { 
          store: new pgSession({conString: process.env.DATABASE_URL,tableName: 'Sessions'}),
          secret: process.env.DATABASE_SECRET,
          resave: false,
          saveUninitialized: false,
          cookie: {maxAge: cookieAge}
        };

  app.use(expressSession(sessionSettings));
  setupPassport();
  app.use(passport.initialize());
  app.use(passport.session());
  //app.use(ensureAuthenticated);

  app.get('/auth/google', passport.authenticate('google', {scope: ['https://www.googleapis.com/auth/userinfo.email']}), (req, res) => {
    // this is being handled by google guys, they are smarter
  });

  app.use('/auth/google/callback', passport.authenticate('google', {failureRedirect: '/'}), (req, res) => {
    res.locals.user = req.user;
    if (req.cookies.loggedIn === undefined) {
      res.cookie('loggedIn', true, {maxAge: cookieAge});
    }
    res.redirect('/');
  });

  // on each request, save user data in res.local so we can use it on views
  app.use((req, res, next) => {
    if (!req.user) {
      req.user = {};
    }
    res.locals.user = req.user;
    next();
  });

  app.get('/logout', (req, res) => {
    if (req.user) {
      logger.action(req.user.name + ' logged out', 'gray');
    }
    req.logout();
    res.cookie('loggedIn', '', {expires: new Date(0)});
    res.redirect('/');
  });
};

回顾一下:

  • 问题在 auth.js 中, req.isAuthenticated() 始终设置为true .

  • 前端使用 document.cookie.indexOf('loggedIn=') === -1; 来确定它是否需要在导航栏中显示登录或注销按钮,按预期工作

  • 如果我退出然后再次登录,我会看到谷歌窗口选择用户(或使用谷歌用户登录),所以这也按预期工作

所以最后唯一真正失败的是 req.isAuthenticated() 无法弄清楚用户是否已注销 . 任何帮助或指示将非常感谢!