You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker部署FastAPI与Streamlit的Cookie/Token获取异常问题

问题

在Docker容器中运行FastAPI应用,尝试从请求中获取token,但无法获取对应的Cookies/Token。相关代码如下:

FastAPI获取Cookie接口代码

@user.get('/get_cookies')
async def get_cookies(request: Request, user: user_dependency):
    if not user:
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
    access_token = request.cookies.get('access_token')
    refresh_token = request.cookies.get('refresh_token')

    print(f"Access Token: {access_token}, Refresh Token: {refresh_token}")
    if access_token and refresh_token:
        return {'access_token': access_token, 'refresh_token': refresh_token}
    else:
        return "Failed to fetch access token and refresh token"

Streamlit应用调用API的代码

import streamlit as st
import requests

p_uri = "http://localhost:8000/user/get_cookies"

response = requests.get(p_uri)
st.write(response.json())

HTTP Cookie设置代码

response = RedirectResponse(url='http://localhost:8501')

response.set_cookie(
    key='jwt_token',
    value=jwt_token,
    httponly=False,
    max_age=60 * 60 * 24 * 30,
    secure=False,
    samesite='lax',
    domain='localhost',
    path='/'
)
response.set_cookie(
    key='access_token',
    value=token,
    max_age=60 * 60 * 24 * 30,
    httponly=False,
    secure=False,
    samesite='lax',
    domain='localhost',
    path='/'
)

response.set_cookie(
    key='refresh_token',
    value=refresh_token,
    max_age=60 * 60 * 24 * 30,
    httponly=False,
    secure=False,
    samesite='lax',
    domain='localhost',
    path='/'
)

return response

解决方案

1. 修正Docker网络与Cookie域名匹配

FastAPI运行在Docker容器内时,localhost指向容器自身而非宿主机。需调整两处配置:

  • 将Streamlit请求地址改为宿主机IP或Docker映射后的宿主机地址(如http://192.168.1.100:8000/user/get_cookies);
  • 避免硬编码localhost为Cookie的domain,通过FastAPI的Request对象动态获取请求主机:
from fastapi import Request

async def set_auth_cookies(request: Request):
    host = request.headers.get('host', '').split(':')[0]
    response = RedirectResponse(url=f'http://{host}:8501')
    response.set_cookie(
        key='access_token',
        value=token,
        max_age=60*60*24*30,
        httponly=False,
        secure=False,
        samesite='lax',
        domain=host,
        path='/'
    )
    # 其他Cookie设置同理
    return response

2. 让Streamlit请求携带Cookie

requests.get默认不会自动携带浏览器中的Cookie,需手动处理:

  • 从Streamlit会话中获取Cookie并传入请求:
import streamlit as st
import requests

# 获取浏览器请求中的Cookie
cookies = st.experimental_get_query_params().get('cookies', {})
# 或从session_state读取已存储的Cookie
# cookies = st.session_state.get('auth_cookies', {})

p_uri = "http://192.168.1.100:8000/user/get_cookies"
response = requests.get(p_uri, cookies=cookies)
st.write(response.json())
  • 或通过前端JS发起请求自动携带Cookie:
import streamlit as st

st.components.v1.html("""
<script>
fetch('http://192.168.1.100:8000/user/get_cookies', {
  credentials: 'include'
})
.then(res => res.json())
.then(data => window.parent.postMessage(data, '*'));
</script>
""", height=0)

def handle_message(msg):
    st.write(msg.data)

st.experimental_set_query_params()
st.experimental_connection("postMessage", on_message=handle_message)

3. 确认Docker端口映射正确

启动FastAPI容器时必须映射端口到宿主机,确保外部能访问:

docker run -p 8000:8000 your-fastapi-image-name

4. 检查SameSite与Secure参数

由于FastAPI(8000端口)和Streamlit(8501端口)属于同一域名下的不同端口,SameSite='lax'是合规的,但需确保secure参数设为False(非HTTPS环境),避免Cookie被浏览器拦截。

内容的提问来源于stack exchange,提问作者Imisioluwa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 10:10:02