我有一個路由登錄最終將創建名為 access_token 的 cookie:someJWT
登錄后,客戶端將收到此 cookie,并將在每次請求時將其發送到服務器,因此無需將 JWT 保存在 localStorage
我怎么沒有找到將這個 cookie 傳遞給 Socket.iO 的方法
我嘗試使用快速會話,但這會將會話 cookie 傳遞給套接字,而不是我需要的
服務器端登錄路徑:
const login = async (req, res) => {
const {email, password} = req.body
const user = await UserModel.findOne({email})
const isMatch = await user.checkPassword(password)
if (isMatch) {
const userToken = JwtService.createToken(user.id)
return res.cookie("access_token", userToken, {
httpOnly: true,
secure: process.env.NODE_ENV === "production"
}).status(200).json({user:user.toJSON(),message: 'login success'})
}
}
插座 :
this.io = new socketio.Server(expressServer, {cors: {origin: 'http://localhost:3000'}})
this.io.use((socket,next)=>{
console.log(socket.handshake.headers.cookie); // undefiend
next()
})
客戶 :
this.socket = socketIOClient(process.env.SOCKET_BASE_URL, {auth: {userId}});
服務器 :
import express, {RequestHandler} from 'express';
import http from 'http'
import cookieParser from "cookie-parser"
import cors from 'cors';
import {router} from '@router';
import dotenv from 'dotenv'
import mongoose from 'mongoose';
import {SocketService} from "@services";
const expressApp = express();
const port = process.env.PORT || 3001;
dotenv.config()
expressApp.use(cors({
origin: true,
credentials: true
}));
expressApp.use(express.json() as RequestHandler);
expressApp.use(cookieParser());
expressApp.use('/', router)
const httpServer = http.createServer(expressApp);
new SocketService(httpServer)
httpServer.listen(port, async () => {
console.log(`server is listening on ${port}`);
try {
await mongoose.connect('mongodb://guess-it-mongo-dev:27017/guess-it', {connectTimeoutMS: 1000});
console.log('connected to mongo server')
} catch (e) {
console.log(e);
}
});
uj5u.com熱心網友回復:
1.解決方案
假設您只有一個 cookie 女巫是您的jwt,您可以使用socket引數獲取它,如下所示:
const token = socket.handshake.headers.cookie.split("=")[1];
如果你有很多 cookie,你需要使用一些 cookie 決議器并給它socket.handshake.headers.cookie決議它,例如:
function getCookie(cName) {
const name = cName "=";
const cDecoded = decodeURIComponent(socket.handshake.headers.cookie);
const cArr = cDecoded.split(';');
let res;
cArr.forEach(val => {
if (val.indexOf(name) === 0) res = val.substring(name.length);
})
return res;
}
const token = getCookie("jwt"); // if your token is called jwt.
2. 故障排除
如果給定的解決方案不適合您,請讓您以這種方式設定應用程式和套接字,以將它們作為單個服務器(隨意更改埠):
const app = express();
const http = require("http");
const server = http.createServer(app);
const { Server } = require("socket.io");
const io = new Server(server);
server.listen(9000, () => {
console.log("server runnig on port " 9000);
});
并且客戶端應該像這樣連接(使用與服務器相同的埠):
import { io } from "socket.io-client";
io("http://localhost:9000/", {
transports: ["websocket"],
});
3. 一個用例
例如,在下面的代碼中,我使用中間件驗證每個連接:
io.use((socket, next) => {
const token = socket.handshake.headers.cookie.split("=")[1];
if (token) {
jwt.verify(token, process.env.SECRET, (err, decodedToken) => {
if (err) {
next(new Error("invalid"));
} else {
User.findById(decodedToken.id, function (err, user) {
if (err) {
next(new Error("invalid"));
} else {
next();
}
});
}
});
} else {
next(new Error("invalid"));
}
});
//if authentication is ok, the code below will get executed
io.on("connection", (socket) => {
// do things
})
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/439214.html
標籤:javascript 节点.js 表示 套接字.io jwt
