跨域登录Directus后跳转管理面板避免重复登录方案咨询
问题描述
已搭建Directus作为后端服务,通过外部域的Django应用表单提交POST请求完成用户登录,但登录成功跳转至Directus管理面板时,仍被要求再次登录,寻求解决方法。
Directus的docker-compose.yaml配置
version: "3" services: db: image: ${DB_IMAGE} container_name: ${DB_CONTAINER_NAME} volumes: - ${DB_VOLUME} ports: - '${DB_PORT}:5432' restart: always environment: - POSTGRES_DB=${DB_DATABASE} - POSTGRES_USER=${DB_USER} - POSTGRES_PASSWORD=${DB_PASSWORD} # - PGDATA=/tmp directus: image: directus/directus:10.7.1 container_name: ${WEB_CONTAINER_NAME} ports: - ${APP_PORT}:8055 restart: always volumes: - ./uploads:/directus/uploads environment: KEY: ${KEY} SECRET: ${SECRET} ADMIN_EMAIL: ${ADMIN_EMAIL} ADMIN_PASSWORD: ${ADMIN_PASSWORD} DB_CLIENT: ${DB_CLIENT} DB_FILENAME: ${DB_FILENAME} DB_HOST: ${DB_HOST} DB_PORT: 5432 DB_DATABASE: ${DB_DATABASE} DB_USER: ${DB_USER} DB_PASSWORD: ${DB_PASSWORD} WEBSOCKETS_ENABLED: true depends_on: - db
Django认证逻辑代码
def authenticate_user(request): print("function called") if request.method == 'POST': email = request.POST.get('email') password = request.POST.get('password') # Create a JSON payload data = { "email": email, "password": password } # Send a POST request to the external API url = "http://<my_domain>:<port>/auth/login" headers = {'Content-Type': 'application/json'} response = requests.post(url, data=json.dumps(data), headers=headers) if response.status_code == 200: # If the response is successful, print it in the console print(response.json()) # Redirect the user to the given URL return redirect("http://<my_domain>:<port>/") else: print(response.json()) return redirect('login_page') else: print(response.json()) return redirect('login_page')
注:已将<my_domain>和<port>替换为真实信息。
解决方法
1. 转发Directus会话Cookie到用户浏览器
当前Django的requests.post是服务器端发起的,登录成功后Directus返回的会话Cookie存储在Django服务器的请求上下文里,并没有传递到用户的浏览器中。跳转时浏览器没有携带Directus的会话Cookie,因此会被要求重新登录。
修改Django认证逻辑,将Directus返回的Cookie设置到用户的响应中:
def authenticate_user(request): print("function called") if request.method == 'POST': email = request.POST.get('email') password = request.POST.get('password') data = { "email": email, "password": password } url = "http://<my_domain>:<port>/auth/login" headers = {'Content-Type': 'application/json'} response = requests.post(url, data=json.dumps(data), headers=headers) if response.status_code == 200: print(response.json()) # 创建跳转响应 redirect_response = redirect("http://<my_domain>:<port>/") # 遍历Directus返回的所有Cookie,转发给用户浏览器 for cookie_name, cookie_value in response.cookies.items(): redirect_response.set_cookie( cookie_name, cookie_value.value, domain=cookie_value.domain, path=cookie_value.path, secure=cookie_value.secure, httponly=cookie_value.httponly, max_age=cookie_value.get('max-age') ) return redirect_response else: print(response.json()) return redirect('login_page') else: # 修正原代码未定义response的问题 return redirect('login_page')
2. 配置Directus的跨域Cookie参数
如果Django和Directus属于不同域名,需要在Directus的docker-compose.yaml环境变量中添加Cookie相关配置,确保Cookie可以跨域传递:
directus: # 其他配置不变 environment: # 原有环境变量保留,新增以下配置 PUBLIC_URL: "http://<your-directus-domain>:<port>" SESSION_COOKIE_DOMAIN: ".your-root-domain.com" # 若为同主域名的子域,使用此配置;不同域名则需调整SameSite SESSION_COOKIE_SAMESITE: "Lax" # 跨域场景下若使用HTTPS,可设置为"None" SESSION_COOKIE_SECURE: "true" # 启用HTTPS时必须设置为true
3. 验证会话Cookie正确性
登录成功后,检查Directus返回的响应头中是否包含directus_session和directus_refresh_token这两个Cookie,它们是维持Directus会话的核心标识。如果缺失,需检查Directus的用户权限配置或登录接口调用是否正确。
内容的提问来源于stack exchange,提问作者Ahmed Wagdi
相关产品推荐
相关产品推荐

