私は、Jared Hanson の素敵なチュートリアル とそれに付随する要点を使用して、passport.js/passport-twitter を私のプロジェクトで動作させようとしています。
言うまでもなく、要点は問題なく機能します。キーを追加し、コールバック URL を変更するだけで機能します。
/etc/hosts の URL「whackypants.dev」を 127.0.0.1 に設定しました。これは、要点の例でうまく機能します。
私の問題は、passport、passport-twitter、connect-ensure-login を既存のアプリに統合しようとすると、かなり奇妙で一貫性のないエラーが発生することです。
/login で [twitter でサインイン] をクリックすると、予想どおり、Twitter に移動し、素敵な oauth トークンが与えられます。
http://whackypants.dev:8080/auth/twitter/callback?oauth_token=I9sGWDKRyWCJcpM3nLx3Tt3sTGRhTVYUKj03ZYIcYk&oauth_verifier=qiRQt1DGpxH2QF4zHrbKbVGj0qXTy5y2S2Sh8Ts10x7
ただし、express は 500 をスローします。
Express
500 failed to fetch user profile (status: 410 data: {"errors": [{"message":
"The Twitter REST API v1 will soon stop functioning. Please migrate to API v1.1.
https://dev.twitter.com/docs/api/1.1/overview.", "code": 68}]})
at /Users/doug/whackypants/node_modules/passport-twitter/lib/passport-
twitter/strategy.js:107:30
at passBackControl (/Users/doug/whackypants/node_modules/passport-
twitter/node_modules/passport-oauth/node_modules/oauth/lib/oauth.js:374:13)
at IncomingMessage. (/Users/doug/whackypants/node_modules/passport-
twitter/node_modules/passport-oauth/node_modules/oauth/lib/oauth.js:386:9)
at IncomingMessage.EventEmitter.emit (events.js:117:20)
at _stream_readable.js:910:16
at process._tickCallback (node.js:415:13)
gist の例で同じエラーがスローされると予想していました。
さらに奇妙な: localhost:8080/login を使用すると、次のようになります。
http://brandery-project.dev:8080/auth/twitter/callback?oauth_token=0PjNkHRMaKjG7KwlXXzUPpiFk6urANvClWK8inB58&oauth_verifier=7A2GtRUf1Q3B2HlxBVGQm4BAQIIEvdYIbBB2GZHBZ
まったく異なる 500 エラー:
Express
500 Error: failed to find request token in session
at Strategy.OAuthStrategy.authenticate (/Users/doug/whackypants/node_modules/passport-
twitter/node_modules/passport-oauth/lib/passport-oauth/strategies/oauth.js:124:54)
at Strategy.authenticate (/Users/doug/whackypants/node_modules/passport-
twitter/lib/passport-twitter/strategy.js:82:40)
at attempt
(/Users/doug/whackypants/node_modules/passport/lib/passport/middleware/
authenticate.js:243:16)
at Passport.authenticate
(/Users/doug/whackypants/node_modules/passport/lib/passport/middleware/
authenticate.js:244:7)
at callbacks (/Users/doug/whackypants/node_modules/express/lib/router/index.js:161:37)
at param (/Users/doug/whackypants/node_modules/express/lib/router/index.js:135:11)
at pass (/Users/doug/whackypants/node_modules/express/lib/router/index.js:142:5)
at Router._dispatch
(/Users/doug/whackypants/node_modules/express/lib/router/index.js:170:5)
at Object.router (/Users/doug/whackypants/node_modules/express/lib/router/index.js:33:10)
at next (/Users/doug/whackypants/node_modules/express/node_modules/connect/lib/
proto.js:190:15)
もう一度 localhost:8080/login にアクセスして更新すると、Cookie に oauth トークンが表示されます。
{
cookie: {
path: '/',
_expires: null,
originalMaxAge: null,
httpOnly: true
},
passport: {},
'oauth:twitter': {
oauth_token: '0PjNkHRMaKjG7KwlXXzUPpiFk6urANvClWK8inB58',
oauth_token_secret: 'aW4zeuCrdrmPxpBzu7U2xDHu1DNQhEFHoGyufhY5mU'
}
}
私はさまざまな問題を理解しようとしてきました。最初は、ミドルウェアをチェーンに配置する順序に関係があるのではないかと思っていましたが、「正しい」ように見えます。
実際のコードは次のとおりです。手がかりに感謝します。
app.js
#!/usr/bin/env node
var fs = require('fs'),
path = require('path'),
express = require('express'),
passport = require('passport'),
exphbs = require('express3-handlebars'),
package = require('./package.json');
var app = express(),
port = process.env.PORT || 8080,
env = process.env.NODE_ENV || 'development';
console.log('\ninitializing ' + package.name + ' (' + env + ')');
// expose application properties to views
app.locals({
app: {
name: package.name,
version: package.version,
env: env
}
});
// set Handlebars as the view engine
console.log('... initializing handlebars view engine');
var hbs = exphbs.create({
defaultLayout: 'main',
helpers: require('./helpers')
});
app.engine('handlebars', hbs.engine);
app.set('view engine', 'handlebars');
app.set('views', __dirname + '/views');
// allow the application to sit behind a proxy
app.enable('trust proxy');
// initialize middleware
console.log('... initializing middleware');
app.use(express.favicon('public/favicon.ico'));
app.use(express.logger());
app.use(express.compress());
app.use(express.static(__dirname + '/public'));
app.use(express.cookieParser());
app.use(express.session({ secret: 'keyboard cat' }));
app.use(passport.initialize());
app.use(passport.session());
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.errorHandler({dumpExceptions: true, showTrace: true}));
// initialize application routes
console.log('... initializing routes');
require('./routes').init(app);
// start server
app.listen(port);
console.log('listening on port ' + port);
ルート/login.js
var passport = require('passport')
, TwitterStrategy = require('passport-twitter').Strategy
, ensureLoggedIn = require('connect-ensure-login').ensureLoggedIn;
exports.init = function(app) {
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(obj, done) {
done(null, obj);
});
var TWITTER_CONSUMER_KEY = "consumerkey";
var TWITTER_CONSUMER_SECRET = "consumersecret";
var TWITTER_CALLBACK_URL = "http://develop.dev:8080/auth/twitter/callback";
passport.use(new TwitterStrategy({
consumerKey: TWITTER_CONSUMER_KEY,
consumerSecret: TWITTER_CONSUMER_SECRET,
callback_url: TWITTER_CALLBACK_URL
}, function(token, tokenSecret, profile, done) {
var user = profile;
return done(null, user);
})
);
app.get('/account', ensureLoggedIn('/login'),
function(req, res) {
console.log(req.session);
res.send('Hello ' + req.user.username);
});
app.get('/login', function(req, res) {
console.log(req.session);
res.send('<html><body><a href="/auth/twitter">Sign in with Twitter</a></body></html>');
});
app.get('/logout', function(req, res) {
req.logout();
res.redirect('/');
});
app.get('/auth/twitter', passport.authenticate('twitter'));
app.get('/auth/twitter/callback', passport.authenticate('twitter', { successReturnToOrRedirect: '/', failureRedirect: '/login' }));
}
ルート/index.js
var login = require('./login');
exports.init = function (app) {
//extraneous api stuff removed
login.init(app);
};