Alf*_*red 62
要求:
var express = require('express'),
app = express.createServer(),
sio = require('socket.io'),
redis = require("redis"),
client = redis.createClient(),
io = null;
/**
* Used to parse cookie
*/
function parse_cookies(_cookies) {
var cookies = {};
_cookies && _cookies.split(';').forEach(function( cookie ) {
var parts = cookie.split('=');
cookies[ parts[ 0 ].trim() ] = ( parts[ 1 ] || '' ).trim();
});
return cookies;
}
app.listen(3000, "localhost");
io = sio.listen(app);
io.of('/private').authorization(function (handshakeData, callback) {
var cookies = parse_cookies(handshakeData.headers.cookie);
client.get(cookies.PHPSESSID, function (err, reply) {
handshakeData.identity = reply;
callback(false, reply !== null);
});
}).on('connection' , function (socket) {
socket.emit('identity', socket.handshake.identity);
});
Run Code Online (Sandbox Code Playgroud)
php with openid authentication => http://dl.dropbox.com/u/314941/6503745/php.tar.gz
登录后,您必须重新加载client.php
进行身份验证
ps:我真的不喜欢创建甚至另一个可能不安全的密码的概念.我建议你看看openID(例如通过谷歌),Facebook Connect(仅举几个选项).
我的问题是,一旦他们通过php/session进行身份验证,那么验证用户是否拥有使用socket.io访问nodejs服务器的正确登录权限的过程是什么?我不希望这个人有权访问nodejs/socket.io函数/服务器,除非他们通过php登录验证.
将唯一的session_id添加到允许的id的列表/集合中,以便socket.io可以授权(搜索授权功能)该连接.我会让PHP使用redis与node.js通信,因为这将是闪电般快/真棒:).现在我正在伪造PHP通信redis-cli
下载redis =>现在可以从以下网址下载稳定版本:http://redis.googlecode.com/files/redis-2.2.11.tar.gz
alfred@alfred-laptop:~$ mkdir ~/6502031
alfred@alfred-laptop:~/6502031$ cd ~/6502031/
alfred@alfred-laptop:~/6502031$ tar xfz redis-2.2.11.tar.gz
alfred@alfred-laptop:~/6502031$ cd redis-2.2.11/src
alfred@alfred-laptop:~/6502031/redis-2.2.11/src$ make # wait couple of seconds
Run Code Online (Sandbox Code Playgroud)
alfred@alfred-laptop:~/6502031/redis-2.2.11/src$ ./redis-server
Run Code Online (Sandbox Code Playgroud)
如果npm
尚未安装,请先访问http://npmjs.org
npm install express
npm install socket.io
npm install redis
Run Code Online (Sandbox Code Playgroud)
列出我已经安装的依赖项,如果根据不兼容性,你也应该安装它们 npm ls
alfred@alfred-laptop:~/node/socketio-demo$ npm ls
/home/alfred/node/socketio-demo
??? express@2.3.12
? ??? connect@1.5.1
? ??? mime@1.2.2
? ??? qs@0.1.0
??? hiredis@0.1.12
??? redis@0.6.0
??? socket.io@0.7.2
??? policyfile@0.0.3
??? socket.io-client@0.7.2
Run Code Online (Sandbox Code Playgroud)
var express = require('express'),
app = express.createServer(),
sio = require('socket.io'),
redis = require("redis"),
client = redis.createClient(),
io = null;
/**
* Used to parse cookie
*/
function parse_cookies(_cookies) {
var cookies = {};
_cookies && _cookies.split(';').forEach(function( cookie ) {
var parts = cookie.split('=');
cookies[ parts[ 0 ].trim() ] = ( parts[ 1 ] || '' ).trim();
});
return cookies;
}
app.listen(3000, "localhost");
io = sio.listen(app);
io.configure(function () {
function auth (data, fn) {
var cookies = parse_cookies(data.headers.cookie);
console.log('PHPSESSID: ' + cookies.PHPSESSID);
client.sismember('sid', cookies.PHPSESSID, function (err , reply) {
fn(null, reply);
});
};
io.set('authorization', auth);
});
io.sockets.on('connection', function (socket) {
socket.emit('access', 'granted');
});
Run Code Online (Sandbox Code Playgroud)
要运行服务器,请运行 node server.js
<?php
session_start();
echo "<h1>SID: " . session_id() . "</h1>";
?>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script src="http://localhost:3000/socket.io/socket.io.js"></script>
</head>
<body>
<p id="text">access denied</p>
<script>
var socket = io.connect('http://localhost:3000/');
socket.on('access', function (data) {
$("#text").html(data);
});
</script>
</body>
Run Code Online (Sandbox Code Playgroud)
当您从Web浏览器加载网页(PHP文件)时,将access denied
显示该消息,但当您将session_id
浏览器中显示的内容添加到redis服务器时,access granted
将显示该消息.当然,通常你不会做任何复制粘贴,只是让PHP直接与Redis通信..但是对于这个演示,您将把SID
ramom807vt1io3sqvmc8m4via1
放入redis,然后授予访问权限.
alfred@alfred-laptop:~/database/redis-2.2.0-rc4/src$ ./redis-cli
redis> sadd sid ramom807vt1io3sqvmc8m4via1
(integer) 1
redis>
Run Code Online (Sandbox Code Playgroud)
请记住,会话只是存储在php会话目录中的文件.node.js从cookie中获取会话ID并检查会话目录中是否确实存在会话ID也不成问题.要获取sessions目录的路径,请参阅php.ini中的session.save_path指令.