【问题标题】:Passport local strategy and cURLPassport 本地策略和 cURL
【发布时间】:2014-04-10 17:26:00
【问题描述】:

我想用 CURL 测试我的 node.js + express + passport.js 测试应用程序(RESTful)。我的代码:

var express = require('express');
var routes = require('./routes');
var http = require('http');
var path = require('path');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;

// Define the strategy to be used by PassportJS
passport.use(new LocalStrategy(
    function(username, password, done) {
        if (username === "admin" && password === "admin") // stupid example
            return done(null, {name: "admin"});

        return done(null, false, { message: 'Incorrect username.' });
    }
));

// Serialized and deserialized methods when got from session
passport.serializeUser(function(user, done) {
    done(null, user);
});

passport.deserializeUser(function(user, done) {
    done(null, user);
});

// Define a middleware function to be used for every secured routes
var auth = function(req, res, next){
    if (!req.isAuthenticated())
        res.send(401);
    else
        next();
};

var app = express();

// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));

// development only
if ('development' == app.get('env')) {
    app.use(express.errorHandler());
}

app.get('/test', auth, function(req, res){
    res.send([{name: "user1"}, {name: "user2"}]);
});

app.post('/login', passport.authenticate('local'), function(req, res) {
    res.send(req.user);
});

使用 curl 调用 /test 和

curl "http://localhost:3000/test"

返回“未授权”(目前为止是正确的)。

使用 curl 调用 /login (POST) 和

curl --data "username=admin&password=admin" http://localhost:3000/login

有效。但是在下一个请求中,我的登录名被“忘记”了。 这是因为 curl 无法处理会话吗?有什么解决方法吗? 我的程序对于 RESTful 应用程序是否正确?

【问题讨论】:

    标签: node.js curl express git-bash passport.js


    【解决方案1】:

    首先,让curl在登录时保存cookie

    curl --cookie-jar jarfile --data "username=admin&password=admin" http://localhost:3000/login
    

    访问/test时读取存储的cookies:

    curl --cookie jarfile "http://localhost:3000/test"
    

    在使用 Node.js v0.10.26 和 Express 3.5.0 在我的机器(Ubuntu 12.04)上运行之前,需要对应用程序本身进行一些修改。我用express --sessions nodetest 生成了一个新的Express 应用程序,并编辑了app.js 中的代码,如下所示。一旦我安装了依赖项,我就运行了该应用程序,它可以使用 curl 命令。

    app.js

    var express = require('express');
    var routes = require('./routes');
    var user = require('./routes/user');
    var http = require('http');
    var path = require('path');
    var passport = require('passport');
    var LocalStrategy = require('passport-local').Strategy;
    
    var app = express();
    
    // Define the strategy to be used by PassportJS
    passport.use(new LocalStrategy(
        function(username, password, done) {
            if (username === "admin" && password === "admin") // stupid example
                return done(null, {name: "admin"});
    
            return done(null, false, { message: 'Incorrect username.' });
        }
    ));
    
    // Serialized and deserialized methods when got from session
    passport.serializeUser(function(user, done) {
        done(null, user);
    });
    
    passport.deserializeUser(function(user, done) {
        done(null, user);
    });
    
    // Define a middleware function to be used for every secured routes
    var auth = function(req, res, next){
        if (!req.isAuthenticated())
            res.send(401);
        else
            next();
    };
    
    // all environments
    app.set('port', process.env.PORT || 3000);
    app.set('views', path.join(__dirname, 'views'));
    app.set('view engine', 'ejs');
    app.use(express.favicon());
    app.use(express.logger('dev'));
    app.use(express.json());
    app.use(express.urlencoded());
    app.use(express.methodOverride());
    app.use(express.cookieParser('your secret here'));
    app.use(express.session());
    app.use(passport.initialize());
    app.use(passport.session());
    app.use(app.router);
    app.use(express.static(path.join(__dirname, 'public')));
    
    // development only
    if ('development' == app.get('env')) {
        app.use(express.errorHandler());
    }
    
    app.get('/test', auth, function(req, res){
        res.send([{name: "user1"}, {name: "user2"}]);
    });
    
    app.post('/login', passport.authenticate('local'), function(req, res) {
        res.send(req.user);
    });
    
    http.createServer(app).listen(app.get('port'), function(){
      console.log('Express server listening on port ' + app.get('port'));
    });
    

    卷曲脚本

    #!/bin/sh
    # curl-login.sh
    rm jarfile
    echo --- login
    curl --cookie-jar jarfile --data "username=admin&password=admin" http://localhost:3000/login
    echo --- test
    curl --cookie jarfile "http://localhost:3000/test"
    

    带有 curl 输出的控制台日志

    $ node app &
    $ sh curl-login.sh
    --- login
    POST /login 200 2ms - 21b
    {
      "name": "admin"
    }--- test
    GET /test 200 1ms - 60b
    [
      {
        "name": "user1"
      },
      {
        "name": "user2"
      }
    ]
    

    注意使用

    app.use(express.cookieParser('your secret here'));
    app.use(express.session());
    

    app.js。如果没有上述两行,会话无法工作。

    您问题中的代码也缺少创建 HTTP 服务器的部分,但我认为这只是复制粘贴问题;我指的是

    http.createServer(app).listen(app.get('port'), function(){
      console.log('Express server listening on port ' + app.get('port'));
    });
    

    【讨论】:

    • 不起作用。关于 curl 手册,命令是curl --cookie cookies.txt --cookie-jar newcookies.txt http://www.example.com。每次通话都必须使用此命令吗?所以:curl --cookie cookies.txt --cookie-jar newcookies.txt --data "username=admin&password=admin" http://localhost:3000/login 然后是curl --cookie cookies.txt --cookie-jar newcookies.txt http://localhost:3000/test?我试过这个。调用 /test 时,我仍然得到:未经授权。 :(
    • 抱歉,我弄错了--cookie-jar/-c 的工作原理(出于某种原因,我认为它使 jar 读/写,而实际上它只写入 cookie 而不会读取它们) .我已经编辑了我的答案;请尝试新版本。
    • 发布您获得的jarfilecurl -v --cookie jarfile "http://localhost:3000/test" 的输出。也许您的 node.js 应用程序需要进行一些更改。
    • “jarfile”保存在哪里?
    • @mosquito87:我编辑了答案以建议对应用程序本身进行更改。
    猜你喜欢
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 2019-03-19
    • 1970-01-01
    • 2017-05-25
    • 2017-02-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多