我对以下情况有些困惑。我正在使用带有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);
};
最后是用于设置所有内容的身份验证文件
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()
无法确定用户已注销。任何帮助或指针将不胜感激!