Passport本地策略和cURL

9

我想使用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应用程序,我的步骤是否正确?

1个回答

13

首先,在使用 curl 登录时,要让它保存 cookies。

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

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

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

在我的机器上(Ubuntu 12.04)使用Node.js v0.10.26和Express 3.5.0之前,需要对应用程序本身进行一些修改才能使其工作。我使用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'));
});

curl脚本

#!/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时,我仍然得到:未经授权。:( - mosquito87
抱歉,我之前对于 --cookie-jar/-c 的工作方式理解有误(由于某些原因,我以为它可以读写 cookie jar,但实际上它只能写入 cookie 而无法读取)。我已经编辑了我的回答,请尝试新版本。 - nwk
请发布您获取的 jarfile 和执行 curl -v --cookie jarfile "http://localhost:3000/test" 命令所得到的输出。或许需要在您的Node.js 应用程序中进行一些更改。 - nwk
'jarfile' 保存在哪里? - mosquito87
1
@mosquito87:我编辑了答案,建议对应用程序本身进行更改。 - nwk
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接