欢迎光临
我们一直在努力

Websocket能携带token过去后端吗

要将 token 传递给 WebSocket,有以下几种常见方法:

方法一:在 WebSocket URL 中添加 token 参数(推荐)

修改 WebSocket URL,将 token 作为查询参数传递:

// 在创建 WebSocket 连接时,将 token 添加到 URL 中
const token = 'your-token-here'; // 从你的 auth 模块获取 token
ws.value = new WebSocket(`${wsUrl.value}?token=${encodeURIComponent(token)}`);

完整的修改示例:

const initWebSocket = () => {
if (ws.value && ws.value.readyState === WebSocket.OPEN) {
ws.value.close();
}

// 获取 token(从你的 auth 模块获取)
const token = getToken(); // 假设你有 getToken() 函数

try {
// 将 token 添加到 URL 中
const fullWsUrl = `${wsUrl.value}?token=${encodeURIComponent(token)}`;
ws.value = new WebSocket(fullWsUrl);

console.log('ws', ws.value);

ws.value.onopen = () => {
console.log('WebSocket 连接成功');
};

// … 其他事件处理代码保持不变
} catch (err) {
console.log('initWebSocket error', err);
}
};

方法二:通过 HTTP 头部传递(需要服务器支持)

如果服务器支持通过 HTTP 头部验证,可以使用以下方式(需要使用 ReconnectingWebSocket 库或自定义实现):

// 需要先安装:npm install reconnecting-websocket
import ReconnectingWebSocket from 'reconnecting-websocket';

const token = getToken();
const rws = new ReconnectingWebSocket(wsUrl.value, [], {
connectionTimeout: 10000,
maxRetries: 3,
headers: {
'Authorization': `Bearer ${token}`,
// 或者
'X-Auth-Token': token
}
});

方法三:连接建立后立即发送认证消息

在 WebSocket 连接建立后,立即发送包含 token 的认证消息:

ws.value.onopen = () => {
console.log('WebSocket 连接成功');

// 连接建立后立即发送认证消息
const token = getToken();
const authMessage = {
type: 'auth',
token: token
};
ws.value.send(JSON.stringify(authMessage));
};

推荐实现

结合代码,推荐使用方法一,因为实现简单且服务器通常支持:

const initWebSocket = () => {
if (ws.value && ws.value.readyState === WebSocket.OPEN) {
ws.value.close();
}

try {
// 从你的 auth 模块获取 token
const token = getToken();

// 将 token 添加到 WebSocket URL 中
const fullWsUrl = token
? `${wsUrl.value}?token=${encodeURIComponent(token)}`
: wsUrl.value;

ws.value = new WebSocket(fullWsUrl);
console.log('ws', ws.value);

ws.value.onopen = () => {
console.log('WebSocket 连接成功');
};

ws.value.onmessage = (e) => {
// … 你现有的消息处理代码
};

ws.value.onclose = () => {
console.log('连接已关闭');
};
} catch (err) {
console.log('initWebSocket error', err);
}
};

注意事项

  • URL 编码:使用 encodeURIComponent() 确保 token 中的特殊字符被正确编码
  • 安全性:URL 中的 token 可能会被记录在服务器日志中,如果安全性要求很高,建议使用方法三
  • 服务器支持:确保你的后端服务器能够从 URL 参数中读取并验证 token
  • 验证是否成功

    你可以在浏览器开发者工具的 Network 标签中查看 WebSocket 连接,确认 URL 中包含了 token 参数。

    这样修改后,你的 WebSocket 连接就会携带 token,服务器端可以根据这个 token 进行身份验证。

    扩展:

    token不放在url,放在header头部,Authorization Bearer + token

    由于 WebSocket 不支持直接设置 HTTP 头部,以下是几种解决方案:

    方法一:连接建立后立即发送认证消息(推荐)

    这是最常用和安全的方式,不会暴露 token 在 URL 中:

    const initWebSocket = () => {
    if (ws.value && ws.value.readyState === WebSocket.OPEN) {
    ws.value.close();
    }

    const token = `Bearer eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6ImZjZTFjZWQ5LTM0ODYtNGQ5Yy05Y2Q4LTI2YzliMzI0MWFjYyJ9.PVvyxvNINiucOZuFadHMaL-7K7hwzeQX9aVpAciNRLMyLGcF7ajKZ3nhKUM6v0rXY8E552_UnCOjp6EA5HrsWw`;

    try {
    // 不在 URL 中传递 token
    ws.value = new WebSocket(wsUrl.value);
    console.log('ws', ws.value);

    ws.value.onopen = () => {
    console.log('WebSocket 连接成功');

    // 连接建立后立即发送认证消息
    const authMessage = {
    type: 'auth',
    token: token
    };
    ws.value.send(JSON.stringify(authMessage));
    };

    ws.value.onmessage = (e) => {
    // 检查是否是认证响应
    if (e.data && typeof e.data === 'string') {
    try {
    const res = JSON.parse(e.data);
    if (res.type === 'auth_response') {
    if (res.success) {
    console.log('WebSocket 认证成功');
    } else {
    console.error('WebSocket 认证失败:', res.message);
    ws.value.close();
    }
    return;
    }
    } catch (error) {
    // 如果不是 JSON 格式的消息,继续处理其他消息
    }
    }

    // 你现有的消息处理代码
    if (e.data === 'DONE') {
    console.log('结束信号');
    ws.value.close();
    return;
    }

    // … 其他消息处理逻辑保持不变
    const res = JSON.parse(e.data);
    // … 你的现有处理逻辑
    };

    ws.value.onclose = () => {
    console.log('连接已关闭');
    };

    ws.value.onerror = (error) => {
    console.error('WebSocket 错误:', error);
    };
    } catch (err) {
    console.log('initWebSocket error', err);
    }
    };

    方法二:使用第三方库(需要安装)

    如果你的服务器支持,可以使用 reconnecting-websocket 库:

    npm install reconnecting-websocket
    import ReconnectingWebSocket from 'reconnecting-websocket';

    const initWebSocket = () => {
    if (ws.value) {
    ws.value.close();
    }

    const token = `Bearer eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6ImZjZTFjZWQ5LTM0ODYtNGQ5Yy05Y2Q4LTI2YzliMzI0MWFjYyJ9.PVvyxvNINiucOZuFadHMaL-7K7hwzeQX9aVpAciNRLMyLGcF7ajKZ3nhKUM6v0rXY8E552_UnCOjp6EA5HrsWw`;

    const rws = new ReconnectingWebSocket(wsUrl.value, [], {
    connectionTimeout: 10000,
    maxRetries: 3,
    WebSocket: class extends WebSocket {
    constructor(url) {
    super(url);
    // 设置自定义头部(需要服务器支持)
    this.protocol = token; // 这个方式可能不被所有服务器支持
    }
    }
    });

    ws.value = rws;

    // … 其他事件处理保持不变
    };

    方法三:使用你的 auth 模块获取 token

    从你的代码中看到你有 getToken 函数,建议使用它:

    import { getToken } from '@/package/utils/auth';

    const initWebSocket = () => {
    if (ws.value && ws.value.readyState === WebSocket.OPEN) {
    ws.value.close();
    }

    // 从 auth 模块获取 token
    const token = getToken();
    if (!token) {
    console.error('未获取到 token,无法建立 WebSocket 连接');
    return;
    }

    const fullToken = `Bearer ${token}`;

    try {
    ws.value = new WebSocket(wsUrl.value);
    console.log('ws', ws.value);

    ws.value.onopen = () => {
    console.log('WebSocket 连接成功');

    // 发送认证消息
    const authMessage = {
    type: 'auth',
    token: fullToken
    };
    ws.value.send(JSON.stringify(authMessage));
    };

    // … 其他处理逻辑保持不变
    } catch (err) {
    console.log('initWebSocket error', err);
    }
    };

    完整的推荐实现

    import { ref, reactive, watch, onUnmounted, onMounted, nextTick } from 'vue';
    import { CircleCloseFilled, Top } from '@element-plus/icons-vue';
    import { BubbleList, Sender, Typewriter } from 'vue-element-plus-x';
    import { getToken } from '@/package/utils/auth'; // 导入你的 auth 模块

    // … 其他代码保持不变

    const initWebSocket = () => {
    if (ws.value && ws.value.readyState === WebSocket.OPEN) {
    ws.value.close();
    }

    // 从 auth 模块获取 token
    const token = getToken();
    if (!token) {
    console.error('未获取到 token,无法建立 WebSocket 连接');
    return;
    }

    const fullToken = `Bearer ${token}`;

    try {
    ws.value = new WebSocket(wsUrl.value);
    console.log('ws', ws.value);

    ws.value.onopen = () => {
    console.log('WebSocket 连接成功');

    // 发送认证消息
    const authMessage = {
    type: 'auth',
    token: fullToken
    };
    ws.value.send(JSON.stringify(authMessage));
    };

    ws.value.onmessage = (e) => {
    // 首先检查是否是认证响应
    if (e.data && typeof e.data === 'string') {
    try {
    const res = JSON.parse(e.data);

    // 如果是认证响应
    if (res.type === 'auth_response') {
    if (res.success) {
    console.log('WebSocket 认证成功');
    } else {
    console.error('WebSocket 认证失败:', res.message);
    ws.value.close();
    }
    return;
    }
    } catch (error) {
    // 如果不是 JSON 格式的消息,继续处理其他消息
    }
    }

    // 原有的消息处理逻辑
    if (e.data === 'DONE') {
    console.log('结束信号');
    ws.value.close();
    return;
    }

    console.log('接收data:', e.data);
    const res = JSON.parse(e.data);
    const msgIndex = res.index;
    if (msgIndex >= 0 && msgIndex < dataList.value.length) {
    const message = dataList.value[msgIndex];
    console.log('message', message);
    if (message) {
    switch (res.type) {
    case 'ai_response':
    message.aiAnswer += res.content;
    message.status = 'done';
    break;

    case 'ai_stream':
    message.aiAnswer += res.chunk;
    message.status = 'streaming';
    break;

    case 'error':
    message.aiAnswer = `[Error] ${res.msg}`;
    message.status = 'error';
    break;
    }
    }
    }

    nextTick(() => {
    scrollToBottom();
    });
    console.log('dataList.value', dataList.value);
    };

    ws.value.onclose = () => {
    console.log('连接已关闭');
    };

    ws.value.onerror = (error) => {
    console.error('WebSocket 错误:', error);
    };
    } catch (err) {
    console.log('initWebSocket error', err);
    }
    };

    // … 其他代码保持不变

    重要提醒

  • 服务器支持:确保你的后端 WebSocket 服务器支持接收认证消息并验证 token
  • 安全考虑:使用认证消息的方式比在 URL 中传递 token 更安全,因为不会在服务器日志中暴露 token
  • 错误处理:添加认证失败的处理逻辑,及时关闭连接避免资源浪费
  • 这是处理 WebSocket 认证的最佳实践方式。

    赞(0)
    未经允许不得转载:171主机测评 » Websocket能携带token过去后端吗
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址