2012-10-14 12 views
8

Zajmuję się tworzeniem strony internetowej za pomocą Node.js (przy użyciu struktury Express). Aby korzystać z uwierzytelniania na Twitterze, używam modułu passport (http://passportjs.org) i jego opakowania na Twitterze o nazwie passport-twitter.Uwierzytelnianie na Twitterze za pomocą oprogramowania pośredniego Passport w węźle

Mój skrypt po stronie serwera jest:

/** 
* 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 wiąże się zalogować jest http://local.host:3000/auth/twitter; kiedy odwiedzam go, Twitter pokazuje mi formę uwierzytelnienia łącząc swoje konto z mojej własnej stronie internetowej, ale po tym etapie pojawia się następujący błąd:

Express 
500 ReferenceError: User is not defined 

Jak mogę rozwiązać ten problem? Pozdrawiam, Vi.

+0

var użytkownika zamiast użytkownikowi var? – chovy

Odpowiedz

7

Musisz określić gdzieś swój typ użytkownika. Wygląda na to, że spodziewasz się, że ta rzecz istnieje i ma funkcje, ale nigdy tego nie zdefiniowałeś. Gdzie znajdujesz tych użytkowników? Te, które nie zostały znalezione, gdzie są "tworzone"? Czy korzystasz z bazy danych? Jak połączyć się z bazą danych? Myślę, że zapomniałeś kroku "Model". Czasami warto spojrzeć na Mongoose Auth który jest jak paszport, ale można podłączyć bezpośrednio do Mongoose, który connnects do Mongo Database

+0

Przepraszam, popełniłem naprawdę głupi błąd! Dziękuję bardzo za odpowiedź! –

+0

po co logować użytkowników potrzebowałeś bazy danych? nie jest "koniecznością". Nie używam żadnej bazy danych w mojej aplikacji, nie mam nic do zapisania .. – vsync

+0

vsync masz rację, nie musisz mieć bazy danych. Tylko jeśli chcesz zachować informacje o użytkowniku od jednego żądania do drugiego, potrzebujesz jakiejś bazy danych (może to być plik, pamięć lub odpowiednia baza danych). – Max

3

To, co zrobiłem, kiedy wychodził ten sam błąd, który mówi User nie jest zdefiniowana:

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

Proszę nie rób tego, to nie jest bezpieczne. Masz jedną instancję "użytkownika", która jest udostępniana wszystkim odwiedzającym Twoją witrynę. Spowoduje to wiele problemów związanych z bezpieczeństwem i kontrolą dostępu. –

+0

ale moja aplikacja mówi, że 'Użytkownik' nie jest zdefiniowany. Muszę ręcznie zdefiniować to. Zaktualizowałem swoją odpowiedź po drodze. – vsync

+0

Dobrze, Użytkownik jest czymś, czego potrzebujesz do wdrożenia się. Zazwyczaj jest to klasa lub model dostarczany przez ORM, taki jak Mongoose. Ważną rzeczą jest to, że powinna istnieć unikalna instancja dla każdego użytkownika aplikacji. –

0

Wpadłem na ten sam problem podczas integracji strategii OAuth2 BeatsMusic dla Paszportu w obrębie Krakena. Wygląda na to, że przykłady różnych strategii integracji z Paszkiem Krakena wykorzystują tę samą prostą przykładową dokumentację, która nie omawiała wyraźnie obiektu użytkownika (zrozumiałe).

Wyjaśniłem (z kopania za pomocą przykładów strategii paszportowej znalezionych @https://github.com/krakenjs/kraken-examples/tree/master/with.passport), że użytkownik ma być modelem opartym na schemacie modelu Mongoose, a także jest skonfigurowany z wtyczką https://github.com/drudge/mongoose-findorcreate.

Po dołączeniu User = require('../PATH_TO/user') i dodano tę wtyczkę do modelu użytkownika, voila! nie ma więcej błędów :)

Wygląda na to, że nie potrzebujesz funkcji DB, więc prawdopodobnie będziesz w stanie usunąć kontrolę auth.

Mam nadzieję, że pomoże to każdemu, kto ma podobne problemy.

0

Myślę, że api nie jest gotowy na przypadki, które nie wymagają integracji db użytkownika. Moim rozwiązaniem było zignorowanie funkcji done() i przekierowanie do strony z wynikami.

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

celu dalszego wyjaśnienia na odpowiedź Maxa: „Musisz utworzyć User sam”

Read Here

TL: DR - Przede wszystkim trzeba mieć userschema który służy do ustawienia użytkowników i zweryfikować użytkowników, potrzebuje backendu manga, który jest łatwy do skonfigurowania.

zasadzie tworzenia tej warstwy pośredniej:

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); 
Powiązane problemy