Skip to content

Instantly share code, notes, and snippets.

@pxsta
Created October 22, 2012 14:44
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save pxsta/3931831 to your computer and use it in GitHub Desktop.
Save pxsta/3931831 to your computer and use it in GitHub Desktop.
Socket.io-Express3.x-session
"use strict";
var express = require('express')
, http = require('http')
, path = require('path')
, io = require('socket.io')
, connect = require("express/node_modules/connect")
, Session = express.session.Session
, app = express();
//メモリストアかRedisのどちらかでセッションを保存
//var sessionStore = new express.session.MemoryStore()
var RedisStore = require('connect-redis')(express)
, sessionStore = new RedisStore();
app.configure(function() {
app.set('port', process.env.PORT || 3000);
//セッションの署名に使われるキー
app.set('secretKey', 'mySecret');
//cookieにexpressのsessionIDを保存する際のキー
app.set('cookieSessionKey', 'sid');
//POSTの値を受け取れるようにする
app.use(express.bodyParser());
//expressでセッション管理を行う
app.use(express.cookieParser(app.get('secretKey')));
app.use(express.session({
key : app.get('cookieSessionKey'),
store : sessionStore
}));
});
app.get('/', function(req, res) {
res.sendfile(__dirname + '/index.html');
});
//ログイン処理
app.post('/user/login', function(req, res) {
var postData = {
userID : req.body.userID,
password : req.body.password
};
//passがtestならログイン成功させる
if ( typeof postData.userID !== 'undefined' && typeof postData.password !== 'undefined' && postData.password.toString() === 'test') {
//sessionにユーザーID保存
req.session.userID = postData.userID.toString();
res.redirect('/chat');
}
else {
console.log('login failed');
res.redirect('/');
}
});
//ログアウト処理
app.get('/user/logout',function(req,res){
req.session.destroy(function(err) {
if(err){
console.log(err);
}
res.redirect('/');
});
});
//チャットページ
app.get('/chat', function(req, res) {
//セッションにuserIDがあったらログイン済みとする
if ( typeof req.session.userID !== 'undefined' && req.session.userID) {
res.sendfile(__dirname + '/chat.html');
}
else {
res.redirect('/');
}
});
io = io.listen(http.createServer(app).listen(app.get('port')), function() {
console.log("Express server & socket.io listening on port " + app.get('port'));
});
//socket.ioのコネクションを認証する前にexpressのセッションIDを元にログイン済みか確認する
io.set('authorization', function(handshakeData, callback) {
if (handshakeData.headers.cookie) {
//cookieを取得
var cookie = require('cookie').parse(decodeURIComponent(handshakeData.headers.cookie));
//cookie中の署名済みの値を元に戻す
cookie = connect.utils.parseSignedCookies(cookie, app.get('secretKey'));
//cookieからexpressのセッションIDを取得する
var sessionID = cookie[app.get('cookieSessionKey')];
// セッションをストレージから取得
sessionStore.get(sessionID, function(err, session) {
if (err) {
//セッションが取得できなかったら
console.dir(err);
callback(err.message, false);
}
else if (!session) {
console.log('session not found');
callback('session not found', false);
}
else {
console.log("authorization success");
// socket.ioからもセッションを参照できるようにする
handshakeData.cookie = cookie;
handshakeData.sessionID = sessionID;
handshakeData.sessionStore = sessionStore;
handshakeData.session = new Session(handshakeData, session);
callback(null, true);
}
});
}
else {
//cookieが見つからなかった時
return callback('cookie not found', false);
}
});
io.sockets.on('connection', function(socket) {
// Expressのセッションをsocket.ioから参照する
console.log('session data', socket.handshake.session);
socket.on("chat", function(message) {
io.sockets.emit("message", socket.handshake.session.userID + " " + message);
});
//Expressのセッションを定期的に更新する
var sessionReloadIntervalID = setInterval(function() {
socket.handshake.session.reload(function() {
socket.handshake.session.touch().save();
});
}, 60 * 2 * 1000);
socket.on("disconnect", function(message) {
clearInterval(sessionReloadIntervalID);
});
});
<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Socket.io-Express3.0.0rc3 session sample</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
</head>
<body>
<h1>Socket.io-Express3.0.0rc3 session sample</h1>
<div id="nav">
<a href="/user/logout">logout</a>
</div>
<div id="chat">
<div id="board"></div>
<textarea id="textarea"></textarea>
<button id="btn-send">send</button>
</div>
</body>
<script type="text/javascript">
var socket = io.connect();
socket.on("message", function(message) {
$("#board").append("<p>" + message + "</p>");
});
var sendMessage = function() {
var message = $("#textarea").val();
$("#textarea").val("");
socket.emit("chat", message);
};
$(document).ready(function() {
$('textarea#textarea').bind('keypress', function(e) {
if (e.keyCode == 13) {
sendMessage();
}
});
$("#btn-send").click(function() {
sendMessage();
});
});
</script>
</html>
<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Socket.io-Express3.0.0rc3 session sample</title>
</head>
<body>
<h1>Socket.io-Express3.0.0rc3 session sample</h1>
<div id="login">
<form action="/user/login" method="post">
ID: <input type="text" name="userID" value="test"/> <br/>
PASS: <input type="text" name="password" value ="test"/>
<input type="submit" value="login" />
</form>
</div>
</body>
</html>
{
"name": "socketio-express3-chat",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node app"
},
"engines": {
"node": "0.8.7",
"npm": "1.1.49"
},
"dependencies": {
"express": "3.0.0rc3",
"socket.io": "0.9.10",
"cookie": "0.0.4",
"connect-redis": "~1.4.4"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment