2013-07-11 16 views
5

私はNodejitsuは、次のエラースピンアウト見つけるために目が覚めた今朝セッション未定義の接続方法-のRedis/ExpressJS /ノード

Warning: connection.session() MemoryStore is not designed for a production environment, as it will leak memory, and will not scale past a single process.

を私は自分自身に考えました - そして、私はもっと適したものを見つけるために行った。私はRedisに着任し、すぐにconnect-redisnode-redisを私のアプリケーションに実装し始めました。

ただし、修正を繰り返しても次のエラーが発生します。以下のようにエラーがある:

TypeError: Cannot set property 'loggedIn' of undefined 
     at /Users/Ryan/Aggregus/server.js:300:25 
     at Promise.<anonymous> (/Users/Ryan/Aggregus/object_models/user.js:60:5) 
     at Promise.<anonymous> (/Users/Ryan/Aggregus/node_modules/mongoose/node_modules/mpromise/lib/promise.js:162:8) 
     at Promise.EventEmitter.emit (events.js:95:17) 
     at Promise.emit (/Users/Ryan/Aggregus/node_modules/mongoose/node_modules/mpromise/lib/promise.js:79:38) 
     at Promise.fulfill (/Users/Ryan/Aggregus/node_modules/mongoose/node_modules/mpromise/lib/promise.js:92:20) 
     at /Users/Ryan/Aggregus/node_modules/mongoose/lib/query.js:1813:13 
     at model.Document.init (/Users/Ryan/Aggregus/node_modules/mongoose/lib/document.js:243:11) 
     at completeOne (/Users/Ryan/Aggregus/node_modules/mongoose/lib/query.js:1811:10) 
     at /Users/Ryan/Aggregus/node_modules/mongoose/lib/query.js:1779:11 

loggedInは単に、req.session.loggedInに私がログインしたユーザーを追跡するために使用するセッション変数を参照しています。以下は、問題のアプリケーションのコードです:

var express = require('express'); 
var crypto = require('crypto'); 
var mongoose = require('mongoose'); 
var nodemailer = require('nodemailer'); 
var request = require('request'); 
var underscore = require('underscore'); 
var mandrill = require('node-mandrill')('0bFNPDenlDiZtu7aXujDQQ'); 
var connect = require('connect'); 
var engines = require('consolidate'); 
var fs = require('fs'); 
var redis = require("redis").createClient(); 

var RedisStore = require('connect-redis')(express); 

var sessionStore = new RedisStore({ 
    client: redis 
}); 

var stripe_api_key = 'KEY'; 
var Stripe = require('stripe')(stripe_api_key); 

var app = express(); 

app.configure(function() { 
    app.engine('html', engines.jade); 
    app.set('view engine', 'html'); 
    app.use(express.cookieParser()); 
    app.use(express.bodyParser()); 
    app.use(express.session({secret: "svtabyrki4q786as37c785ta8vi56aiw4i8w467acv", store: sessionStore})); 
    app.use(express.static(__dirname + '/www')); 
    app.use(express.compress()); 
    app.use(app.router); 

}); 

// Mongoose Connection 

var db = mongoose.connection; 

var dbURI = 'HIDDENURL'; 

db.on('disconnected', function() { 
    mongoose.connect(dbURI, {server:{auto_reconnect:true}}); 
}); 

db.on('error', function(error) { 
    console.error('Error in MongoDb connection: ' + error); 
    mongoose.disconnect(); 
}); 

mongoose.connect(dbURI, {server:{auto_reconnect:true}}); 

// Mongoose Object Models 

var User = require('./object_models/user')(mongoose, nodemailer, mandrill); 
var Notifications = require('./object_models/notification')(mongoose, nodemailer); 
var Experience = require('./object_models/experience')(mongoose, nodemailer); 
var Booking = require('./object_models/booking')(mongoose, nodemailer); 
var Review = require('./object_models/review')(mongoose, nodemailer); 
var Heart = require('./object_models/heart')(mongoose, nodemailer); 
var Message = require('./object_models/message')(mongoose, nodemailer); 

// Nodemailer Settings 

var smtpTransport = nodemailer.createTransport("SMTP",{ 
    service: "Gmail", 
    auth: { 
     user: "[email protected]", 
     pass: pwd 
    } 
}); 

// Bootstrap Call 

app.get('/', function(req, res) { 
    res.render('../index.html'); 
    console.log("WUSUP"); 
}); 

ここでは、さらに明瞭さを提供するために、私は無駄にこの時点までしようとしたものです:

  1. 私は前express.sessionコールにapp.use(express.cookieParser());を配置していますこの主題の大部分の記事が示唆したように、
  2. new RedisStoreコールが初期化時に直接clientを参照することを保証しました。
  3. 私はexpress.sessionと 'express.cookieParser'の両方のinit呼び出しの後にapp.use(app.router)を配置しました。
  4. 私のRedisサーバーは、createClient()コールで完全に機能しています。

このsimilar questionは、初期化されているセッションストアを表現するためにapp.router前呼び出すために、むしろ些細app.use初期化を防止することにより解決しました。

したがって、TL; DR:connect-redisを使用すると、私のセッション変数はundefinedを返します。私は答えのためにウェブを精査しました。私の唯一の手がかりは、Expressの独自のセッション処理の前にapp.routerが開始されていることです。その小さな不具合が私を超えています。スタックオーバーフローの神は私の貧しい魂に慈悲を持っています。

編集:package.jsonは参考になるかもしれません。 NodeJitsu経由で生成:

{ 
    "name": "Aggregus", 
    "subdomain": "aggregus-Aggregus", 
    "scripts": { 
    "start": "node server.js" 
    }, 
    "version": "0.0.0-14", 
    "engines": { 
    "node": "0.8.x" 
    }, 
    "dependencies": { 
    "connect": "2.7.8", 
    "consolidate": "0.9.1", 
    "express": "3.2.2", 
    "jade": "0.30.0", 
    "mongoose": "3.6.9", 
    "node-mandrill":"1.0.1", 
    "nodemailer": "0.4.1", 
    "request":"2.22.0", 
    "stripe": "1.3.0", 
    "underscore":"1.4.4" 
    } 
} 

答えて

5

あなたはconnect-redisを間違って呼び出しているため、別途Redisをインストールする必要はありません。しかし、私はあなたのpackage.jsonにconnect-redisが表示されないので、npm install --save connect-redisにしてください。

var express = require('express'); 
var RedisStore = require('connect-redis')(express); 
var ports = require('./classes/ports.js'); 
var config = require('./config/config.js'); 
var routes = require('./routes'); 
var errors = require('./classes/errors.js'); 

var app = express(); 
ports(app); 
app 
.use(express.logger()) 
.use(express.compress()) 
.use(express.cookieParser()) 
.use(express.session({ 
    store: new RedisStore({ 
    port: config.redisPort, 
    host: config.redisHost, 
    db: config.redisDatabase, 
    pass: config.redisPassword 
    }), 
    secret: 'Your secret here', 
    proxy: true, 
    cookie: { secure: true } 
})) 
.use(express.favicon(__dirname + '/../public/img/favicon.ico')) 
.use(express.bodyParser()) 
.use(express.methodOverride()) 

routes(app); 
errors(app); 
+0

Hey @dankohnリクエストを渡す前にクッキーからreq.userをすぐに設定する機能を設定するにはどうすればよいですか? – morgs32

+0

ほとんどの場合、パスポートまたはすべてのオートを使用したいと思っています。クッキーを設定する例を上に示します。http://stackoverflow.com/questions/20484649/csrf-token-not-working-when-submitting-form-in-express/20485620#20485620 – dankohn