8

我正在使用 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

我怎么解决这个问题?最好的问候,六。

4

5 回答 5

7

您必须在某处定义您的用户类型。看起来您希望这个东西User存在并具有功能findOrCreateand findById,但您从未在任何地方定义过。您在哪里“找到”这些用户?那些没有被发现的,它们在哪里被“创造”?你在使用数据库吗?你如何连接到数据库?我认为您忘记了“模型”步骤。你可能想看看Mongoose Auth,它类似于 Passport,但它直接插入Mongoose,它连接到Mongo数据库

于 2012-10-14T20:40:26.630 回答
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);
  }
));
于 2013-08-06T09:21:30.947 回答
0

在 Kraken 中集成 Passport 的 BeatsMusic OAuth2 策略时遇到了同样的问题。看起来各种 Kraken Passport 集成策略的示例使用相同的简单示例文档,该文档没有明确讨论 User 对象(可以理解)。

我发现(通过挖掘通过 @ https://github.com/krakenjs/kraken-examples/tree/master/with.passport找到的护照策略示例)用户旨在成为基于猫鼬模型模式的模型并且还配置了https://github.com/drudge/mongoose-findorcreate插件。

在我包含User = require('../PATH_TO/user')并将这个插件添加到用户模型之后,瞧!没有更多的错误:)

听起来您不需要数据库功能,因此您可能很适合删除身份验证检查。

希望这对其他有类似问题的人有所帮助。

于 2014-08-07T19:26:40.347 回答
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');
  }
));
于 2015-05-12T15:22:43.773 回答
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);
于 2016-10-25T20:27:58.497 回答