我对以下情况有点困惑 . 我正在使用带有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()
无法弄清楚用户是否已注销 . 任何帮助或指示将非常感谢!