我有一个登录路径,最终创建了一个名为access_token的jwt cookie.登录后,客户端将收到此cookie,并在每次请求时发送它.然而,我没有找到一种方法把这个cookies 传给插座.伊奥.

服务器端登录路径:

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);
            }
        });

推荐答案

1.解决方案

假设你只有一个cookie witch是你的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
})

Javascript相关问答推荐

Redux工具包查询(RTKQ)端点无效并重新验证多次触发

从mat—country—select获取整个Country数组

jQuery提交按钮重新加载页面,即使在WordPress中使用preventDefault()

如何从隐藏/显示中删除其中一个点击?

如何根据当前打开的BottomTab Screeb动态加载React组件?

JSDoc创建并从另一个文件导入类型

Websocket错误—有一个或多个保留位开启:reserved1 = 1,reserved2 = 0,reserved3 = 0

我怎么才能得到Kotlin的密文?

使用Promise.All并发解决时,每个promise 的线性时间增加?

Angular 订阅部分相互依赖并返回数组多个异步Http调用

将核心模块导入另一个组件模块时存在多个主题

在我的index.html页面上找不到我的Java脚本条形图

Jest toHaveBeenNthCalledWith返回当前设置的变量值,而不是调用时的值

搜索功能不是在分页的每一页上进行搜索

使用RxJS from Event和@ViewChild vs KeyUp事件和RxJS主题更改输入字段值

在SuperBase JS客户端中寻址JSON数据

JWT Cookie安全性

顶点图使用组标签更新列之间的条宽

为什么我看到的是回复,而不是我的文档?

是否有静态版本的`instanceof`?