我正在使用Node.js开发一个网站(使用Express框架)。为了使用Twitter身份验证,我使用的是passport
模块(http://passportjs.org),而他的Twitter包装器名为passport-twitter
。
我的服务器端脚本是:
/**
* Module dependencies.
*/
var express = require('express')
, routes = require('./routes')
, user = require('./routes/user')
, http = require('http')
, path = require('path')
, passport = require('passport')
, keys = require('./oauth/keys')
, TwitterStrategy = require("passport-twitter").Strategy;
var app = express();
app.configure(function(){
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser('foo'));
app.use(express.session());
// Initialize Passport! Also use passport.session() middleware, to support
// persistent login sessions (recommended).
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
app.use(require('less-middleware')({ src: __dirname + '/public' }));
app.use(express.static(path.join(__dirname, 'public')));
});
app.configure('development', function(){
app.use(express.errorHandler());
});
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function (err, user) {
done(err, user);
});
});
passport.use(new TwitterStrategy({
consumerKey: keys.twitterConsumerKey,
consumerSecret: keys.twitterConsumerSecret,
callbackURL: "http://local.host:3000/auth/twitter/callback"
},
function(token, tokenSecret, profile, done) {
User.findOrCreate({ twitterId: profile.id }, function (err, user) {
if (err) { return done(err); }
else { return done(null, user); }
});
}
));
app.get('/', routes.index);
app.get('/contacts', routes.contacts);
app.get('/cv', routes.cv);
app.get('/projects', routes.projects);
app.get('/users', user.list);
// Redirect the user to Twitter for authentication.
// When complete, Twitter will redirect the user back to the
// application at /auth/twitter/callback
app.get('/auth/twitter', passport.authenticate('twitter'));
// Twitter will redirect the user to this URL after approval. Finish the
// authentication process by attempting to obtain an access token. If
// access was granted, the user will be logged in. Otherwise,
// authentication has failed.
app.get('/auth/twitter/callback',
passport.authenticate('twitter',
{
successRedirect: '/',
failureRedirect: '/login'
}
)
);
http.createServer(app).listen(app.get('port'), function(){
console.log("Express server listening on port " + app.get('port'));
});
与登录相关联的URI为http://local.host:3000/auth/twitter
;当我访问它时,Twitter向我显示了将我的帐户与我自己的网站链接的身份验证表单,但在此步骤之后,会出现以下错误:
Express
500 ReferenceError: User is not defined
我该如何解决这个问题? 最好的问候,Vi。
答案 0 :(得分:7)
您必须在某处定义用户类型。看起来你希望这个东西User
存在并且具有函数findOrCreate
和findById
,但你从未在任何地方定义过它。你在哪里“找到”这些用户?那些没有找到的,他们在哪里“被创造”?你在使用数据库吗?你如何连接到数据库?我想你忘了“模特”一步。您可能需要查看Mongoose Auth,它类似于Passport,但它会直接插入Mongoose,它连接到Mongo数据库
答案 1 :(得分:3)
这是我在遇到同样的错误时所做的,即User
未定义:
passport.use(new TwitterStrategy({
consumerKey: keys.twitterConsumerKey,
consumerSecret: keys.twitterConsumerSecret,
callbackURL: "http://local.host:3000/auth/twitter/callback"
},
function(token, tokenSecret, profile, done) {
done(null, profile);
}
));
答案 2 :(得分:0)
在Kraken中为Passport集成BeatsMusic OAuth2策略时遇到了同样的问题。看起来各种Kraken Passport集成策略的示例使用相同的简单示例文档,该文档未明确讨论User对象(可理解)。
我发现(通过挖掘护照策略示例@ https://github.com/krakenjs/kraken-examples/tree/master/with.passport),用户打算成为基于Mongoose模型架构的模型,并且还配置了https://github.com/drudge/mongoose-findorcreate插件。
在我加入User = require('../PATH_TO/user')
并将此插件添加到用户模型后,瞧!没有更多的错误:)
听起来你不需要数据库功能,所以你可能不喜欢删除身份验证。
希望这有助于其他有类似问题的人。
答案 3 :(得分:0)
我认为api还没有为不需要用户数据库集成的情况做好准备。我的解决方案是忽略done()
函数并重定向到成功页面。
passport.use(new TwitterStrategy({
consumerKey: keys.twitterConsumerKey,
consumerSecret: keys.twitterConsumerSecret,
callbackURL: "http://local.host:3000/auth/twitter/callback"
},
function(token, tokenSecret, profile, done) {
//done(null, profile);
this.redirect('/auth/success');
}
));
答案 4 :(得分:0)
要进一步解释Max的答案:“你需要自己创建User
”
TL:DR - 基本上你必须有一个用于设置用户和验证用户的用户密码,它需要一个mongoose db后端,这实际上很容易配置。
基本上创建这个中间件:
var mongoose = require('mongoose');
var bcrypt = require('bcrypt-nodejs');
// define the schema for our user model
var userSchema = mongoose.Schema({
local : {
email : String,
password : String,
group : String,
},
facebook : {
id : String,
token : String,
email : String,
name : String
},
twitter : {
id : String,
token : String,
displayName : String,
username : String
},
google : {
id : String,
token : String,
email : String,
name : String
}
});
// methods ======================
// generating a hash
userSchema.methods.generateHash = function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};
// checking if password is valid
userSchema.methods.validPassword = function(password) {
return bcrypt.compareSync(password, this.local.password);
};
// create the model for users and expose it to our app
module.exports = mongoose.model('User', userSchema);