javascript - 认证问题

标签 javascript node.js authentication express passport.js

在使用 Passport 本地策略为我的 restful api 实现身份验证时,我遇到了一个混淆问题。

注意: 当我在我的 index.js 中完成这一切时,我的身份验证工作成功。但我想在类中使用以实现更好的代码分离。

我有一个 passport.js 模块

// config/passport.js

// load all the things we need
var LocalStrategy   = require('passport-local').Strategy;
// load up the user model
var mysql = require('mysql');
var dbconfig = require('./database');
var connection = mysql.createConnection(dbconfig.connection);

module.exports = function(passport) {

// passport needs ability to serialize and unserialize users out of session
    passport.serializeUser(function (user, done) {
        //console.log("SER");
        console.log(user),
        done(null, user);
    });
    passport.deserializeUser(function (user, done) {
        console.log("XXXX");
        console.log(user);
        connection.query("SELECT * FROM users WHERE name = ? ",user.name, function(err, rows){
            console.log("DER");
            console.log(rows);
            done(err, rows[0]);
        });
    });

// passport local strategy for local-login, local refers to this app
    passport.use('local-login', new LocalStrategy(
        function (username, password, done) {
            console.log("hhh");
            console.log(username);
            connection.query("SELECT * FROM users WHERE name = ? ",username, function(err, rows){
                console.log(rows);
                return done(err, rows[0]);
            });
        })
    );

    // route middleware to ensure user is logged in
    function isLoggedIn(req, res, next) {
        if (req.isAuthenticated())
            return next();

        res.sendStatus(401);
    }
};

这是我的 Controller 类:

class AuthenticateController {
    constructor(router, passport) {
        this.router = router;
        this.registerRoutes();
        this.passport = passport;
    }

    registerRoutes() {
        this.router.post('/login/:username/:password', this.login.bind(this));
        //this.router.get('/logout', this.logout.bind(this));
        this.router.get('/content', this.content.bind(this));
    }

    login(req, res) {
        this.passport.authenticate("local-login", { failureRedirect: "/login"}),
            res.redirect("/content");
    }

    content(req, res ) {
        console.log(req.user);
        if (req.isAuthenticated()) {
            res.send("Congratulations! you've successfully logged in.")
        } else {
            res.sendStatus(401);
        }
    }
  isLoggedIn(req, res, next) {
    console.log(req.user);
    if (req.isAuthenticated())
        return next();

    res.sendStatus(401);
}
}

module.exports = AuthenticateController;

Controller 从我的 index.js 中获取完全配置为参数的路由器和通行证。

//index.js

var express = require('express')
    , cors = require('cors')
    , app = express()
    , passport = require('passport')
    , morgan = require('morgan');

require('./config/passport')(passport); // pass passport for configuration

var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(require('express-session')({secret: 'vidyapathaisalwaysrunning',
    resave: true,
    saveUninitialized: true }));

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

var apiRouter = express.Router();
app.use('/api', apiRouter);
//
var apiV1 = express.Router();
apiRouter.use('/v1', apiV1);

var authenticateApiV1 = express.Router();
apiV1.use('/auth', authenticateApiV1);

var AuthenticateController = require('./controllers/authenticate');
var ac = new AuthenticateController(authenticateApiV1, passport);   //pass in our fully configured passport

//If I call this /login instead of the /auth/login/ in the Controller Class it works!
//app.post("/login",
//    passport.authenticate("local-login", { failureRedirect: "/login"}),
//    function (req, res) {
//        res.redirect("/content");
//    });

什么有效,什么无效

general 中的身份验证正在运行。在我发布的 index.js 中,您会看到 app.post("/login", ...。如果我调用这个,则身份验证成功,如果我尝试访问受限内容 req.user 有一个值(用户对象),我可以成功调用 req.isAuthenticated()

但是,如果我使用来自 /auth/login/username/password 的身份验证,则 req.user 在尝试访问时是 undefined受限制的内容。 我没有收到任何错误和 /auth/login/username/password/ HTTP 代码 301 的响应 - '重定向到/content。

我目前不知道我在这里做错了什么,我对 Node/express/passport 这个话题还很陌生..

希望有人有想法。如果您需要其他帮助我,请在评论中提及,我会尽力为您提供所需的一切。

谢谢

编辑:

我最近尝试读取登录函数中的req.user,即使在那里它也是未定义的

login(req, res) {
        this.passport.authenticate("local-login", { failureRedirect: "/login"}),
            console.log(req.user) //undefined
            res.redirect("/content");
    }

我想这可能是一些异步问题,我应该使用一些回调函数,但我不知道如何在我的 login() 中应用它

编辑 2:

我面临的另一个问题是 isLoggedIn() 请求的集成。

如果我这样做:

registerRoutes() {
                this.router.get('/', this.isLoggedIn, this.getUsers.bind(this));
                this.router.get('/:id', this.getSingleUser.bind(this));
            }

它导致 401 - Unauthorized

isLoggedIn() 中的 console.log(req.user); 导致未定义。

但是如果我调用第一个路由而不调用 isLoggedIn() 并执行 console.log(req.user); 用户对象存在。

最佳答案

对于本地策略,正确使用带有 Passport 身份验证的回调可以如下所示:

function(req, res, next){ passport.authenticate('local-login', function(err, user, info){ if(err) return logger.log('error', err); if(user) req.login(user, function(err){ if(err) return next(err); return res.json({'success': true}); }); if(!user) return res.json({'error':true, 'message': info.message, 'type': info.type}); })(req, res, next);<br/> }

请注意使用 req.login() 在 session 中显式设置用户。

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

相关文章:

node.js - Cosmos DB 通过部分文档更新进行增量

javascript - Node express : Requests are taking Top-level domain as the subdomain ? ?

Java - 使用用户身份验证访问文件

java - 如何使用登录组件安排程序流程

javascript - 共享内置原型(prototype)的 Node JavaScript 上下文?

javascript - React Native 接收新的 props,componentWillReceiveProps

javascript - 在node.js中查找主机?

node.js - 通过我的 REST API 和 Facebook 进行用户身份验证

javascript - Apache Cordova 3 插件不工作

javascript - 如何将包含左浮动元素的元素居中?