跳到主要內容

Express Error: connect.cookieParser("secret") required for security when using sessions

注意到了嗎?最近expressjs升版了,目前版本是Express 3.0.0 Alpha1

# npm list express
npm WARN ls doesn't take positional args. Try the 'search' command
/root
├── ejs@0.7.1 
├─┬ express@3.0.0alpha1 
│ ├── commander@0.5.2 
│ ├─┬ connect@2.1.2 
│ │ ├── crc@0.1.0 
....
  │ └── semver@1.0.13 
  ├── sprintf@0.1.1 
  └─┬ ssh-agent@0.1.0 
    └── ctype@0.5.0 

但是使用了新的版本,執行上卻出現不明的Exception...
仔細檢查與舊版本間的差異...發現2.x跟3.x的版本有不少地方不一樣
直覺下做了幾個測試:

1. 2.x執行3.x所產生程式碼....無法執行,3.x的一些宣告2.x不認得,應該是function有做過修改...
# node app.js 
node.js:201
        throw e; // process.nextTick error, or 'error' event on first tick
              ^
TypeError: object is not a function
    at Object.CALL_NON_FUNCTION (native)
    at Object.<anonymous> (/root/TestPrj2/app.js:10:11)
    at Module._compile (module.js:441:26)
    at Object..js (module.js:459:10)
    at Module.load (module.js:348:31)
    at Function._load (module.js:308:12)
    at Array.0 (module.js:479:10)
    at EventEmitter._tickCallback (node.js:192:40)
2. 3.x執行2.x所產生程式碼....無法執行,有下面exception...判斷是某些物件欄位修改了...
# node app.js 
node.js:201
        throw e; // process.nextTick error, or 'error' event on first tick
              ^
TypeError: Object function app(req, res){ app.handle(req, res); } has no method 'address'
    at Server.<anonymous> (/tmp/T1/app.js:40:69)
    at Server.g (events.js:156:14)
    at Server.emit (events.js:64:17)
    at Array.0 (net.js:777:10)
    at EventEmitter._tickCallback (node.js:192:40)
3. 3.x執行session設定....無法執行,這個我還沒找出來3.x怎麼設定session而不會有錯誤@@
# node app.js 
Error: connect.cookieParser("secret") required for security when using sessions
    at Object.session [as handle] (/tmp/T1/node_modules/express/node_modules/connect/lib/middleware/session.js:212:28)
    at next (/tmp/T1/node_modules/express/node_modules/connect/lib/proto.js:191:15)
    at Object.cookieParser [as handle] (/tmp/T1/node_modules/express/node_modules/connect/lib/middleware/cookieParser.js:60:5)
    at next (/tmp/T1/node_modules/express/node_modules/connect/lib/proto.js:191:15)
    at multipart (/tmp/T1/node_modules/express/node_modules/connect/lib/middleware/multipart.js:45:61)
    at /tmp/T1/node_modules/express/node_modules/connect/lib/middleware/bodyParser.js:57:9
    at urlencoded (/tmp/T1/node_modules/express/node_modules/connect/lib/middleware/urlencoded.js:34:72)
    at /tmp/T1/node_modules/express/node_modules/connect/lib/middleware/bodyParser.js:55:7
    at json (/tmp/T1/node_modules/express/node_modules/connect/lib/middleware/json.js:41:55)
    at Object.bodyParser [as handle] (/tmp/T1/node_modules/express/node_modules/connect/lib/middleware/bodyParser.js:53:5)


下面是我遇到的問題....在把jade改成ejs時候還OK,但是設定session部分就會有錯誤:

使用3.0產生之原始碼:

/**
 * Module dependencies.
 */
var express = require('express')
  , routes = require('./routes')
  , http = require('http');
var app = express();
app.configure(function(){
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.favicon());
  app.use(express.logger('dev'));
  app.use(express.static(__dirname + '/public'));
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(app.router);
});
app.configure('development', function(){
  app.use(express.errorHandler());
});
app.get('/', routes.index);
http.createServer(app).listen(3000);
console.log("Express server listening on port 3000");

修改成使用ejs做view presentation

/**
 * Module dependencies.
 */
var express = require('express')
  , routes = require('./routes')
  , http = require('http');
var app = express();
app.configure(function(){
    app.set('views', __dirname + '/views');
    app.set('view engine', 'ejs');
    app.use(express.bodyParser());
    app.use(express.cookieParser());
    app.use(express.session({ secret: "keyboard cat" }));
    app.use(express.methodOverride());
    app.use(app.router);
    app.use(express.static(__dirname + '/public'));
    app.set("view options", {layout : false});
})
app.get('/', function(req, res){
    res.render('index', {
      title: 'I am Benson'
    });
});
http.createServer(app).listen(3000);
console.log("Express server listening on port 3000");
比對一下2.x產生的程式碼:
/**
 * Module dependencies.
 */
var express = require('express')
  , routes = require('./routes');
var app = module.exports = express.createServer();
// Configuration
app.configure(function(){
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(app.router);
  app.use(express.static(__dirname + '/public'));
});
app.configure('development', function(){
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
app.configure('production', function(){
  app.use(express.errorHandler());
});
// Routes
app.get('/', routes.index);
app.listen(3000, function(){
  console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
});

2與3的差異部分大致上是紅色部分

而3.x在加上了session設定後執行錯誤如下:
[root@bensonS64PLUS1 ~/TestPrj]# node app.js                                                                                                                                                              
Express server listening on port 3000
Error: connect.cookieParser("secret") required for security when using sessions
    at Object.session [as handle] (/root/TestPrj/node_modules/express/node_modules/connect/lib/middleware/session.js:212:28)
    at next (/root/TestPrj/node_modules/express/node_modules/connect/lib/proto.js:191:15)
    at Object.cookieParser [as handle] (/root/TestPrj/node_modules/express/node_modules/connect/lib/middleware/cookieParser.js:60:5)
    at next (/root/TestPrj/node_modules/express/node_modules/connect/lib/proto.js:191:15)
    at multipart (/root/TestPrj/node_modules/express/node_modules/connect/lib/middleware/multipart.js:45:61)
    at /root/TestPrj/node_modules/express/node_modules/connect/lib/middleware/bodyParser.js:57:9
    at urlencoded (/root/TestPrj/node_modules/express/node_modules/connect/lib/middleware/urlencoded.js:34:72)
    at /root/TestPrj/node_modules/express/node_modules/connect/lib/middleware/bodyParser.js:55:7
    at json (/root/TestPrj/node_modules/express/node_modules/connect/lib/middleware/json.js:41:55)
    at Object.bodyParser [as handle] (/root/TestPrj/node_modules/express/node_modules/connect/lib/middleware/bodyParser.js:53:5)

目前還未找到session如何使用2.x的寫法,暫時可以解決的方法如下:
1. 取消"app.use(express.session({ secret: "keyboard cat" }));"
2. 降版express:
$ npm uninstall express
$ npm uninstall express -gd
$ npm install express@2.5.9
$ npm install express@2.5.9 -gd
如果採用將版的選擇
請不要忘記修改專案package的定義
# vi package.json 
{
    "name": "application-name"
  , "version": "0.0.1"
  , "private": true
  , "dependencies": {
      "express": "2.5.8"
    , "jade": ">= 0.0.1"
  }
}

附註:
express 3.0的產生的原始碼於2.*是不能用的,專案需要重新產生
或是修改幾個部分:
1. 修改express宣告:
var app = express(); //3.0
修改為
var app = module.exports = express.createServer();
2. 修改http server建立宣告
http.createServer(app).listen(3000); //3.0
修改為
app.listen(3000, function(){
  console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
});


附註:
確認您的express版本
# npm list express
npm WARN ls doesn't take positional args. Try the 'search' command
application-name@0.0.1 /tmp/T1
├── ejs@0.7.1  extraneous
├─┬ express@2.5.8 
│ ├─┬ connect@1.8.7 
│ │ └── formidable@1.0.9 
│ ├── mime@1.2.4 
│ ├── mkdirp@0.3.0 
│ └── qs@0.4.2 
└─┬ jade@0.25.0 
  ├── commander@0.5.2 
  └── mkdirp@0.3.0 








這個網誌中的熱門文章

Oracle LISTAGG

同事介紹的一個Oracle的好用查詢:LISTAGG
SELECT A.GROUP_ID,A.KEY, LISTAGG(A.VALUE,'; ')WITHINGROUP(ORDERBYA.VALUE)as GG  fromSYS_PROPERTIESaGROUP byA.GROUP_ID,A.KEY
LISTAGG可以將group後的結果會總顯示於一個欄位 上述SQL原本A.VALUE會是一個row一個row的排列 使用LISTAGG之後,可以將A.VALUE顯示在同一個row中 並且可以指定間隔符號(在此設定為';') 針對某一些報表查詢非常有用唷 :D

使用GCP Cloud Builder建置CI/CD Flow

服務的建置通常是持續性的作業,而部署則一般是專案初期建置一次,未來可以沿用該部署設定... 這樣的流程走向自動化,在Container的環境又更是重要... 本篇介紹一下,在Google雲端,我們可以搭配Source Repository與Build Trigger等服務來完成服務的自動建置與部屬,讓封裝Container與部署到Container Engine的動作可以一氣呵成...
首先幾單瞭解一下一個Container Engine服務的建置與部屬過程...
使先,建立Container Engine Cluster,透過GCP Winzard可以很快速地開立您的GKE Cluster…

假設您的cluster是叫做demo-cluster,則可以透過下面的指令來跟GKE建立連線
$ gcloud container clusters get-credentials demo-cluster --zone asia-east1-a
這串指令不用記ㄛ~可以在Cluster的頁面找到他...

點選複製,即可貼到您的Terminal執行...

跟GKE建立鏈結後,接下來可以部署您的城市,這邊我們以我的一個範例程式Demoweb (https://github.com/peihsinsu/demoweb) 為例,

這個專案中,包含幾個重要結構:
app/ : 放置您的程式,在Dockerfile中會將該資料匣複製到Docker Image中 k8s/ : 放置k8s的deployment與service描述檔 Dockerfile : 封裝docker的描述檔,會以node.js的image為基礎來建置執行環境 cloudbuild.yaml : Google Cloud Build Trigger的步驟描述檔

使用 minikube 輕鬆上手 kubernetes

安裝minikube
macOS只需要透過brew即可快速安裝...
brew cask install minikube
Linux環境可以直接下載執行檔,放到環境變數可以吃到的路徑即可...
curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 && \ chmod +x minikube && \
sudo mv minikube /usr/local/bin/
Windows的下載網址如下: https://storage.googleapis.com/minikube/releases/latest/minikube-windows-amd64.exe
如果您的kubectl尚未安裝,可以直接使用google cloud sdk來安裝:
curl https://sdk.cloud.google.com | bash
gcloud components install kubectl
安裝完成後,原則上minikube會在本地端加入minikube的k8s context,我們可以透過下面指令來使用該context…
kubectl config use-context minikube
然後,可檢查一下您的minikube node是否正常運作....