2012-10-14 34 views
8

Tôi đang phát triển một trang web có Node.js (sử dụng khung Express). Để sử dụng xác thực Twitter, tôi đang sử dụng mô-đun passport (http://passportjs.org) và trình bao bọc của mình cho Twitter được gọi là passport-twitter.Xác thực Twitter với phần mềm trung gian hộ chiếu trong Node

My server-side script là:

/** 
* 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 liên quan đến đăng nhập là http://local.host:3000/auth/twitter; khi tôi truy cập vào nó, Twitter chỉ cho tôi dưới hình thức xác thực cho liên kết tài khoản của tôi với trang web riêng của tôi, nhưng, sau bước này, các lỗi sau xảy ra:

Express 
500 ReferenceError: User is not defined 

Làm thế nào tôi có thể giải quyết vấn đề này? Trân trọng, Vi.

+0

var tài khoản thay vì var sử dụng? – chovy

Trả lời

7

Bạn phải xác định Kiểu người dùng của mình ở đâu đó. Có vẻ như bạn mong đợi điều này User để tồn tại và có các chức năng findOrCreatefindById, nhưng bạn chưa bao giờ định nghĩa ở bất cứ đâu. Bạn đang 'tìm kiếm' những người dùng này ở đâu? Những thứ không được tìm thấy, chúng được tạo ra ở đâu? Bạn đang sử dụng một cơ sở dữ liệu? Làm thế nào để bạn kết nối với cơ sở dữ liệu? Tôi nghĩ bạn đã quên bước "Mô hình". Bạn có thể muốn có một cái nhìn tại Mongoose Auth mà là giống như hộ chiếu nhưng nó cắm trực tiếp vào Mongoose, mà connnects đến một cơ sở dữ liệu Mongo

+0

Tôi xin lỗi, tôi đã thực hiện một lỗi thực sự ngu ngốc! Cảm ơn bạn rất nhiều vì câu trả lời! –

+0

tại sao bạn cần bất kỳ cơ sở dữ liệu nào khi người dùng đăng nhập? nó không phải là "phải". Tôi không sử dụng bất kỳ cơ sở dữ liệu nào trong ứng dụng của mình, tôi không có gì để lưu .. – vsync

+0

vsync bạn đúng, bạn không cần phải có cơ sở dữ liệu. Chỉ khi bạn muốn duy trì thông tin người dùng từ yêu cầu này đến yêu cầu khác, bạn cần một số loại cơ sở dữ liệu (có thể là tệp, trong bộ nhớ hoặc cơ sở dữ liệu thích hợp). – Max

3

Đây là những gì tôi đã làm khi tôi phải đối mặt với lỗi tương tự mà nói User không được định nghĩa:

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

Xin đừng làm điều này, nó không an toàn. Bạn có một cá thể 'Người dùng' duy nhất, được chia sẻ giữa tất cả khách truy cập vào trang web của bạn. Điều này sẽ gây ra nhiều vấn đề về bảo mật và kiểm soát truy cập. –

+0

nhưng ứng dụng của tôi cho biết 'Người dùng' không được xác định. Tôi phải tự định nghĩa nó. Tôi đã cập nhật câu trả lời của mình theo cách thức – vsync

+0

Quyền, Người dùng là thứ bạn cần để thực hiện chính mình. Nó thường là một lớp hoặc mô hình được cung cấp bởi một ORM như Mongoose. Điều quan trọng là phải có một ví dụ duy nhất cho mỗi người dùng ứng dụng của bạn. –

0

Tôi đã gặp sự cố tương tự khi tích hợp chiến lược BeatsMusic OAuth2 cho Hộ chiếu trong Kraken. Có vẻ như các ví dụ cho các chiến lược tích hợp Kraken Passport khác nhau sử dụng cùng một tài liệu ví dụ đơn giản mà không thảo luận rõ ràng về đối tượng User (dễ hiểu).

Tôi đã tìm ra (từ đào qua các ví dụ về chiến lược hộ chiếu được tìm thấy @https://github.com/krakenjs/kraken-examples/tree/master/with.passport) Người dùng dự định là một mô hình dựa trên giản đồ mô hình Mongoose và cũng được định cấu hình bằng plugin https://github.com/drudge/mongoose-findorcreate.

Sau khi tôi bao gồm User = require('../PATH_TO/user') và thêm plugin này vào mẫu Người dùng, thì đấy! không còn lỗi nào nữa :)

Có vẻ như bạn không cần chức năng DB, vì vậy bạn có thể làm tốt việc xóa kiểm tra xác thực.

Hy vọng điều này sẽ giúp cho bất kỳ ai khác có vấn đề tương tự.

0

Tôi cho rằng api chưa sẵn sàng cho các trường hợp không cần tích hợp db của người dùng. Giải pháp của tôi đã bỏ qua chức năng done() và chuyển hướng đến trang thành công.

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'); 
    } 
)); 
0

Để giải thích thêm về câu trả lời của Max: "Bạn cần phải Tạo User mình"

Read Here

TL: DR - Về cơ bản bạn cần phải có một userschema mà bạn sử dụng để thiết lập người dùng và xác minh người dùng, nó cần một chương trình phụ trợ db mongoose, mà thực sự là đơn giản để cấu hình.

về cơ bản tạo middleware này:

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); 
Các vấn đề liên quan