lobehub / lobe-chat

🤯 Lobe Chat - an open-source, modern-design AI chat framework. Supports Multi AI Providers( OpenAI / Claude 3 / Gemini / Ollama / Azure / DeepSeek), Knowledge Base (file upload / knowledge management / RAG ), Multi-Modals (Vision/TTS) and plugin system. One-click FREE deployment of your private ChatGPT/ Claude application.
https://chat-preview.lobehub.com
Other
40.97k stars 9.34k forks source link

[Bug] 使用Docker部署并frp、CF Tunnels进行https转发后无法正常使用 #3763

Closed aiqinxuancai closed 1 week ago

aiqinxuancai commented 2 weeks ago

📦 部署环境

Docker

📌 软件版本

最新

💻 系统环境

Other Linux

🌐 浏览器

Chrome

🐛 问题描述

我在unraid中使用docker部署了lobe-chat,从本地ip访问 http://172.16.1.13:3210/ 一切正常,输入访问密码后可以正常对话。

然后我将此地址通过frp以及cf Tunnels使用https域名访问,这两个均在对话时出现如下错误

{
  "error": {
    "code": "ERR_JWT_EXPIRED",
    "name": "s",
    "claim": "exp",
    "reason": "check_failed",
    "payload": {
      "accessCode": "xxxxxx",
      "userId": "166e28dd-8fdd-4004-b6bb-ae8478b0700c",
      "iat": 1725438857,
      "exp": 1725438957
    }
  },
  "code": "ERR_JWT_EXPIRED",
  "name": "s",
  "claim": "exp",
  "reason": "check_failed",
  "payload": {
    "accessCode": "xxxxxx",
    "userId": "166e28dd-8fdd-4004-b6bb-ae8478b0700c",
    "iat": 1725438857,
    "exp": 1725438957
  },
  "provider": "openai"
}

image

📷 复现步骤

通过docker部署,并在公网通过转发,https域名访问

🚦 期望结果

能和内网一样使用

📝 补充信息

我查找之前的issues,看到有说时间问题,我核对了服务器时间和本地时间均没有任何问题,并且2个域名无法访问的同时,内网地址保持正常使用。

lobehubbot commented 2 weeks ago

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


📦 Deployment environment

Docker

📌 Software version

up to date

💻 System environment

Other Linux

🌐 Browser

Chrome

🐛 Problem description

I deployed lobe-chat using docker in unraid, and accessed http://172.16.1.13:3210/ from the local IP. Everything was normal. After entering the access password, I could have a normal conversation.

Then I accessed this address using https domain name through frp and cf Tunnels, both of which gave the following error during the conversation

{
  "error": {
    "code": "ERR_JWT_EXPIRED",
    "name": "s",
    "claim": "exp",
    "reason": "check_failed",
    "payload": {
      "accessCode": "xxxxxx",
      "userId": "166e28dd-8fdd-4004-b6bb-ae8478b0700c",
      "iat": 1725438857,
      "exp": 1725438957
    }
  },
  "code": "ERR_JWT_EXPIRED",
  "name": "s",
  "claim": "exp",
  "reason": "check_failed",
  "payload": {
    "accessCode": "xxxxxx",
    "userId": "166e28dd-8fdd-4004-b6bb-ae8478b0700c",
    "iat": 1725438857,
    "exp": 1725438957
  },
  "provider": "openai"
}

image

📷 Steps to reproduce

Deployed through docker and accessed through forwarding and https domain name on the public network

🚦 Expected results

Can be used the same as intranet

📝 Supplementary information

I searched for previous issues and saw that there was a time issue. I checked the server time and local time and there were no problems. Moreover, while the two domain names were inaccessible, the intranet address remained in normal use.

lobehubbot commented 2 weeks ago

👀 @aiqinxuancai

Thank you for raising an issue. We will investigate into the matter and get back to you as soon as possible. Please make sure you have given us as much context as possible.\ 非常感谢您提交 issue。我们会尽快调查此事,并尽快回复您。 请确保您已经提供了尽可能多的背景信息。

aiqinxuancai commented 2 weeks ago

我测试将内网端口通过frp转发为HTTP协议时,一切正常,我认为是仅转发为HTTPS时存在问题,结合输出的iat和exp相差100秒,我找到了此文件,我觉得这个函数对HTTPS的转发处理可能存在问题。 https://github.com/lobehub/lobe-chat/blob/77243e12a4c9b538d54524e793cac0dda3d3839c/src/utils/jwt.ts#L7

lobehubbot commented 2 weeks ago

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


When I tested forwarding the intranet port to the HTTP protocol through frp, everything was normal. I thought there was a problem when forwarding only to HTTPS. Combined with the difference between the output iat and exp of 100 seconds, I found this file. I think this function is suitable for HTTPS. There may be a problem with forwarding processing. https://github.com/lobehub/lobe-chat/blob/77243e12a4c9b538d54524e793cac0dda3d3839c/src/utils/jwt.ts#L7

arvinxx commented 1 week ago

是不是存在时区差异导致转发时间计算不对呢?

lobehubbot commented 1 week ago

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


Is there a time zone difference that causes the forwarding time to be calculated incorrectly?

aiqinxuancai commented 1 week ago

是不是存在时区差异导致转发时间计算不对呢?

时区如果是差的话,不会只100秒,而且主要是,内网通过HTTP访问完全没问题。。。

lobehubbot commented 1 week ago

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


Is there a time zone difference that causes the forwarding time to be calculated incorrectly?

If the time zone is different, it will not be just 100 seconds, and mainly, there is no problem accessing the intranet through HTTP. . .

arvinxx commented 1 week ago

能详细介绍下你的请求链路吗?

lobehubbot commented 1 week ago

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


Can you describe your request link in detail?

aiqinxuancai commented 1 week ago

能详细介绍下你的请求链路吗?

在Unraid中直接部署非数据库版本,对外的端口是3210,内网IP访问和使用均正常。 然后我有一台有公网IP的设备,上面装了frps,在本地使用frp映射https协议,配置如下

[[proxies]]
name = "lbhttps"
type = "https"
customDomains = ["lb.xxxxxx.me"]
[proxies.plugin]
type = "https2http"
localAddr = "172.16.1.13:3210"
crtPath = "/etc/frp/cert/lb.xxxxxx.me.pem"
keyPath = "/etc/frp/cert/lb.xxxxxx.me.key"
requestHeaders.set.x-from-where = "frp"

xxxxxx为隐去的部分。

映射后,访问域名httsp://lb.xxxxxx.me:xxxx可以正常访问到页面,但发送任何对话内容,均是返回我主体上所说的错误信息。

同一时刻,访问 http://172.16.1.13:3210 ,一切正常。


然后我认为可能是frp有什么问题,然后使用了cf tunnels内网穿透映射,穿透出来也是https+域名访问,同样是能访问,但无法会话。

lobehubbot commented 1 week ago

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


Can you introduce your request link in detail?

Deploy the non-database version directly in Unraid, the external port is 3210, and the intranet IP access and use are normal. Then I have a device with a public IP and frps installed on it. I use frp locally to map the https protocol. The configuration is as follows

[[proxies]]
name = "lbhttps"
type = "https"
customDomains = ["lb.xxxxxx.me"]
[proxies.plugin]
type = "https2http"
localAddr = "172.16.1.13:3210"
crtPath = "/etc/frp/cert/lb.xxxxxx.me.pem"
keyPath = "/etc/frp/cert/lb.xxxxxx.me.key"
requestHeaders.set.x-from-where = "frp"

xxxxxx is the hidden part.

After mapping, when accessing the domain name http://lb.xxxxxx.me:xxxx, the page can be accessed normally, but any conversation content sent will return the error message mentioned on my main body.

At the same time, when accessing http://172.16.1.13:3210, everything is normal.


Then I thought there might be something wrong with frp, and then used cf tunnels intranet penetration mapping. When it penetrated, it was also https+domain name access. It was also accessible, but the session could not be held.

arvinxx commented 1 week ago

这个 JWT 抛错的含义是, payload 鉴权 token 过期。你看到的 100s 是指过期时间是 100s。

image

建议你检查下你的本地 docker 镜像的时区是否是和你电脑一致的。如果时区不一致是有可能导致这个问题的。


纯 HTTP 访问正常的原因是在构造 JWT 时 http 模式下会不做加密直接 base64 一下传递,服务端解析的时候针对 http 的场景是用的另外一套验证逻辑

lobehubbot commented 1 week ago

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


The meaning of this JWT error is that the payload authentication token has expired. The 100s you see means the expiration time is 100s.

image

It is recommended that you check whether the time zone of your local docker image is consistent with that of your computer. This problem may occur if the time zones are inconsistent.


The reason why pure HTTP access is normal is that when constructing JWT, it will be directly passed through base64 without encryption in http mode. When the server parses, another set of verification logic is used for the http scenario.

aiqinxuancai commented 1 week ago

这个 JWT 抛错的含义是, payload 鉴权 token 过期。你看到的 100s 是指过期时间是 100s。

image

建议你检查下你的本地 docker 镜像的时区是否是和你电脑一致的。如果时区不一致是有可能导致这个问题的。

纯 HTTP 访问正常的原因是在构造 JWT 时 http 模式下会不做加密直接 base64 一下传递,服务端解析的时候针对 http 的场景是用的另外一套验证逻辑

我要检查一下是不是unraid的时间有什么问题

lobehubbot commented 1 week ago

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


The meaning of this JWT error is that the payload authentication token has expired. The 100s you see means the expiration time is 100s.

image

It is recommended that you check whether the time zone of your local docker image is consistent with your computer. This problem may occur if the time zones are inconsistent.

The reason why pure HTTP access is normal is that when constructing JWT, it will be directly passed through base64 without encryption in http mode. When the server parses, another set of verification logic is used for the http scenario.

I want to check if there is something wrong with the unraid time.

aiqinxuancai commented 1 week ago

这个 JWT 抛错的含义是, payload 鉴权 token 过期。你看到的 100s 是指过期时间是 100s。

image

建议你检查下你的本地 docker 镜像的时区是否是和你电脑一致的。如果时区不一致是有可能导致这个问题的。

纯 HTTP 访问正常的原因是在构造 JWT 时 http 模式下会不做加密直接 base64 一下传递,服务端解析的时候针对 http 的场景是用的另外一套验证逻辑

给unraid自己写了个docker进去输出了一下UTC时间,确实时间不正确,检查发现系统的ntp没生效,似乎没正确更新。问题已解决,感谢!

lobehubbot commented 1 week ago

✅ @aiqinxuancai

This issue is closed, If you have any questions, you can comment and reply.\ 此问题已经关闭。如果您有任何问题,可以留言并回复。

lobehubbot commented 1 week ago

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


The meaning of this JWT error is that the payload authentication token has expired. The 100s you see means the expiration time is 100s.

image

It is recommended that you check whether the time zone of your local docker image is consistent with your computer. This problem may occur if the time zones are inconsistent.

The reason why pure HTTP access is normal is that when constructing JWT, it will be directly passed through base64 without encryption in http mode. When the server parses, another set of verification logic is used for the http scenario.

I wrote a docker for unraid and entered it to output the UTC time. The time was indeed incorrect. I checked and found that the system's ntp did not take effect and seemed to have not been updated correctly. The problem has been solved, thank you!