javascript - Passport ensureAuthenticated

标签 javascript node.js passport.js

我想使用 Passport.jsGithub Strategy 实现登录。这是我使用的代码:

...

/* Ensure Auth function */
function ensureAuthenticated(req, res, next){
    if (req.isAuthenticated()) return next()
    else res.redirect('/');
}

/* Some modules */
global.passport = require('passport');
global.GithubStrategy = require('passport-github2').Strategy;
global.util = require('util');
global.session = require('express-session');
global.bodyParser = require('body-parser');
global.methodOverride = require('method-override');
global.partials = require('express-partials');
global.request = require('request');

/* Passport */
passport.serializeUser(function(user, done){
  	done(null, user);
});
passport.deserializeUser(function(obj, done){
  	done(null, obj);
});
passport.use(new GithubStrategy({
        clientID: config.githubID,
        clientSecret: config.githubSecret,
        callbackURL: config.githubURL
    },
    function(accessToken, refreshToken, profile, done){
        process.nextTick(function(){
            return done(null, profile);
        });
    }
));
app.use(partials());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(methodOverride());
app.use(session({secret: 'keyboard cat', resave: false, saveUninitialized: false}));
app.use(passport.initialize());
app.use(passport.session());

/* Controllers */
app.get('/auth/github', passport.authenticate('github', {scope: ['user:email']}), function(req, res){});
app.get('/auth/github/callback', passport.authenticate('github', { failureRedirect: '/' }), function(req, res){
    res.redirect('/dashboard');
});
app.get('/logout', function(req, res){
  	req.logout();
  	res.redirect('/');
});

我在 Passport.js 文档中搜索了很多,但找不到这个问题的答案:

  • 为什么在我的例子中, session 不保存身份验证?例如,如果我在路由上设置 ensureAuthenticated 中间件,它总是将我重定向到/,这是登录表单。
  • 为什么我无法从 req.user 访问用户信息以查看用户信息?
  • 为什么logout 路由不起作用?

最佳答案

前言/前言

我对 Local Strategy 也有同样的问题.我没有太多关于您的系统架构的信息,但是我的系统使用了以下内容:

  • PassportJS(带本地策略)
  • ExpressJS 处理 session 和路由(带 Redis MemoryStore)
  • NodeJS 服务器
  • AngularJS 2 前端

要结帐的东西

  1. CORS 在这个问题上发挥了重要作用。

我使用了 cors图书馆来缓解我在那里遇到的问题。特别是,我对配置进行了以下更改:

let cors_config = {
    origin: "http://localhost:8080",
    credentials: true
};

这会将您的 CORS 设置配置为在预检请求中包含 Access-Control-Allow-Credentials: true header 。

  1. 确保您的内存存储和 session 配置正确

从没有指定内存存储(默认为 LocalStore)开始,然后从那里开始工作。我看到您现在没有使用,所以请继续阅读。

server.use(session({
    secret: "secret_c0de",
    resave: false,
    saveUninitialized: false//,
    //store: new redis_store(redis_settings)
}));

检查验证时是否在验证后返回 session cookie。它应该包含一个键值,键值为“connect.sid”,即您的 session ID。

如果您没有获得 session cookie,那么您就知道您的 session 可能配置不正确,在这种情况下您应该:

  • 检查“使用”调用的加载顺序
  • 尝试找出 session 处理代码的任何错误或问题

如果您正在接收 cookie,但 isAuthenticated() 检查在后续请求中失败,这通常暗示您的 MemoryStore 不工作。

  • 如果您最初使用的是 LocalStore,则不需要太多配置,因此再次提示您的 session 配置存在问题
  • 如果您使用的是像 Redis 这样的商店,请尝试收听 Redis events (主要是“连接”和“错误”)并将输出记录到控制台,以便您查看它是否正常工作。

我在您的代码中注意到的事情

  • 检查您的序列化函数,您正在序列化整个用户对象。

这更像是一种优化,但已经注意到人们在序列化和反序列化用户 ID 方面取得了更大的成功。

passport.serializeUser(function(user, done){
    done(null, user.id);
});
passport.deserializeUser(function(obj, done){
    User.findById(obj, function(err, user){
        if(err){/*code to handle error with not finding user*/}
        done(null, user);
    });
});
  • 您应该要求 cookie-parser因为 session 使用 session cookie。

回答您的问题

  • 为什么在我的情况下, session 不保存身份验证?

session 创建在您的应用程序中被破坏,因此您应该尝试调试它。如上所述,您应该在身份验证请求后检查 session ID 是否在 session cookie 中返回,然后从那里继续。

  • 为什么我无法从 req.user 访问用户信息以查看用户信息?

用户在从 Passport 成功反序列化尝试后被注入(inject)。在您的情况下, session 从一开始就不会创建,也不会序列化到您的 MemoryStore 中,因此永远无法反序列化(因为它不存在)。

  • 为什么注销路由不起作用?

req.logout() 只会在创建成功的 session 时起作用。 从您提供的其他代码和信息来看,我认为这就是您所指的内容。

希望您能在这里找到一些有值(value)的信息,如果您想特别聊聊,请随时发表评论! :)

关于javascript - Passport ensureAuthenticated,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42912926/

相关文章:

javascript - 将 D3 中的工具提示添加到 Google map 叠加层

node.js - twilio 向调用者说些什么(node.js)

javascript - RavenDB 无法在 nodejs 上使用 AND 运算符执行搜索

javascript - Express.js、Passport.js 和 SockJS : How to attach user socket to deserializeUser

javascript - 如何调用同名的父函数?

javascript - 如何在 javascript 上添加 onBlur 函数

mysql - Nodejs Passport 设置困惑

node.js - Passport JS Google OAuth2 - 强制登录或帐户选择器

javascript - Ace 编辑器,如何删除除一个之外的所有 keyBindings?

javascript - 使用 Express REST API 编辑帖子