Nodejs Socket.io 验证
Nodejs Socket.io 验证
客户端:index.html
<html>
<head>
<script src="http://localhost:3000/socket.io/socket.io.js" type="text/javascript"></script>
<script type="text/javascript">
tick = io.connect('http://localhost:3000/');
tick.on('data', function (data) {
console.log(data);
});
tick.on('error', function (reason){
console.error('Unable to connect Socket.IO', reason);
});
tick.on('connect', function (){
console.info('successfully established a working and authorized connection');
});
</script>
</head>
<body>
Open the browser console to see tick-tocks!
</body>
</html>
设置Express
var app = express();
app.configure(function () {
app.use(express.cookieParser());
app.use(express.session({secret: 'secret', key: 'express.sid'}));
});
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
server = http.createServer(app)
server.listen(3000);
io = io.listen(server);
io.set('authorization', function (handshakeData, accept) {
if (handshakeData.headers.cookie) {
handshakeData.cookie = cookie.parse(handshakeData.headers.cookie);
handshakeData.sessionID = connect.utils.parseSignedCookie(handshakeData.cookie['express.sid'], 'secret');
if (handshakeData.cookie['express.sid'] == handshakeData.sessionID) {
return accept('Cookie is invalid.', false);
}
} else {
return accept('No cookie transmitted.', false);
}
accept(null, true);
});
为了实现 Node.js
和 Socket.IO
的验证机制,我们需要确保客户端与服务器之间的连接是经过身份验证的。这里我们将通过检查 cookie
来验证客户端的身份。
客户端代码 (index.html
)
首先,客户端需要加载 Socket.IO
库,并尝试连接到服务器:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Socket.IO Authentication Example</title>
<script src="http://localhost:3000/socket.io/socket.io.js" type="text/javascript"></script>
<script type="text/javascript">
var socket = io.connect('http://localhost:3000/', {
transports: ['websocket'],
query: "authToken=yourAuthToken"
});
socket.on('connect', function () {
console.info('Successfully established a working and authorized connection');
});
socket.on('data', function (data) {
console.log(data);
});
socket.on('error', function (reason) {
console.error('Unable to connect Socket.IO', reason);
});
</script>
</head>
<body>
Open the browser console to see tick-tocks!
</body>
</html>
服务器端代码
接下来,在服务器端设置 Express
和 Socket.IO
,并添加身份验证逻辑:
const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const cookieParser = require('cookie-parser');
const session = require('express-session');
const connect = require('connect'); // Ensure you have this package installed
const app = express();
// 设置中间件
app.use(cookieParser());
app.use(session({
secret: 'secret',
key: 'express.sid'
}));
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
const server = http.createServer(app);
const io = socketIo.listen(server);
io.set('authorization', function (handshakeData, accept) {
if (handshakeData.headers.cookie) {
const cookies = cookieParser.parse(handshakeData.headers.cookie);
const sessionID = cookies['express.sid'];
// 检查 session ID 是否有效
if (!sessionID || !connect.utils.parseSignedCookie(sessionID, 'secret')) {
return accept('Session ID is invalid.', false);
}
} else {
return accept('No cookie transmitted.', false);
}
accept(null, true);
});
io.on('connection', function (socket) {
console.log('A user connected');
socket.on('disconnect', function () {
console.log('User disconnected');
});
});
server.listen(3000, () => {
console.log('Server running on port 3000');
});
解释
-
客户端:客户端发送一个带有
authToken
的查询参数,这在实际应用中可以替换为任何有效的认证信息。 -
服务器端:使用
express-session
中间件来管理会话。当客户端尝试连接时,服务器通过检查cookie
中的express.sid
来验证用户的身份。如果cookie
无效或不存在,连接将被拒绝。
通过这种方式,我们可以确保只有经过身份验证的客户端才能与服务器建立有效的 WebSocket 连接。
能讲下 做什么用的吗
为了确保在使用Socket.io时进行有效的验证,我们可以利用Session信息来验证客户端的身份。以下是一个简化的示例代码,展示如何在Node.js中配置Socket.io以实现客户端的身份验证。
首先,我们需要确保客户端请求包含正确的Cookie。在服务端,我们将使用cookie-parser
和express-session
中间件来解析和管理Session信息。接着,在Socket.io的授权过程中,我们将检查客户端是否提供了有效的Session信息。
客户端代码 (index.html
)
客户端代码不需要修改,因为它已经通过socket.io.js
库连接到服务器,并且监听了相关的事件。
<html>
<head>
<script src="http://localhost:3000/socket.io/socket.io.js" type="text/javascript"></script>
<script type="text/javascript">
var socket = io.connect('http://localhost:3000/');
socket.on('data', function (data) {
console.log(data);
});
socket.on('error', function (reason) {
console.error('Unable to connect Socket.IO', reason);
});
socket.on('connect', function () {
console.info('Successfully established a working and authorized connection');
});
</script>
</head>
<body>
Open the browser console to see tick-tocks!
</body>
</html>
服务端代码
服务端需要引入必要的依赖项,并配置cookie-parser
、express-session
以及Socket.io。
const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const cookieParser = require('cookie-parser');
const session = require('express-session');
const connect = require('connect'); // 注意这里可能需要安装额外的包如`connect`或使用其他方法来处理session
const cookie = require('cookie');
const app = express();
app.use(cookieParser());
app.use(session({
secret: 'secret',
key: 'express.sid'
}));
app.get('/', function (req, res) {
res.sendFile(__dirname + '/index.html');
});
const server = http.createServer(app);
const io = socketIo.listen(server);
io.set('authorization', function (handshakeData, accept) {
if (handshakeData.headers.cookie) {
handshakeData.cookie = cookie.parse(handshakeData.headers.cookie);
handshakeData.sessionID = connect.utils.parseSignedCookie(handshakeData.cookie['express.sid'], 'secret');
if (!handshakeData.sessionID || handshakeData.sessionID !== handshakeData.cookie['express.sid']) {
return accept('Invalid session cookie', false);
}
} else {
return accept('No cookie transmitted.', false);
}
accept(null, true);
});
server.listen(3000, () => {
console.log('Server listening on port 3000');
});
解释
- 客户端:客户端尝试通过Socket.io与服务器建立连接。如果连接成功,它会在控制台输出一条消息。
- 服务端:
- 使用
cookie-parser
和express-session
中间件来解析和管理会话。 - 在Socket.io的
authorization
函数中,我们检查传入的HTTP请求头中是否包含有效的Cookie。如果Cookie有效,则接受连接;否则,拒绝连接。
- 使用
这样,我们就实现了基本的身份验证机制,确保只有经过身份验证的用户才能建立Socket.io连接。