React SPA与自托管Directus 9.21.2实现SSO自动登录需求求助
解决方案
针对Directus 9.21.2自托管版本,实现React SPA登录后自动登录Directus后台的需求,有两种实用方案:
方案一:临时登录令牌(Magic Link)机制
利用Directus提供的临时登录令牌接口,通过SPA已有的有效凭证生成一次性登录链接,打开Directus时自动完成登录。
实现步骤:
- 调用Directus生成临时登录令牌
在SPA中,当用户已登录(持有有效的access token),调用/auth/login/token接口生成临时令牌。该接口需要使用当前用户的access token授权。 - 构造自动登录链接并打开新标签
用返回的令牌拼接Directus登录链接,打开新标签后Directus会自动验证令牌并完成登录。
React代码示例:
const openDirectusAutoLogin = async () => { const directusUrl = process.env.REACT_APP_DIRECTUS_URL; // 假设SPA将access token存在localStorage中,根据实际存储位置调整 const currentAccessToken = localStorage.getItem('directus_access_token'); // 从SPA已获取的用户信息中拿到当前用户ID const currentUserId = localStorage.getItem('directus_user_id'); if (!currentAccessToken || !currentUserId) { // 无有效凭证,直接打开Directus登录页 window.open(directusUrl, '_blank'); return; } try { const response = await fetch(`${directusUrl}/auth/login/token`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${currentAccessToken}` }, body: JSON.stringify({ user: currentUserId, expires: 60 // 令牌有效期设为60秒,足够完成跳转登录 }) }); const data = await response.json(); if (data.token) { // 构造自动登录链接并打开新标签 window.open(`${directusUrl}/auth/login?token=${data.token}`, '_blank'); } else { throw new Error('未生成有效登录令牌'); } } catch (error) { console.error('生成Directus登录令牌失败:', error); // 失败时回退到直接打开Directus登录页 window.open(directusUrl, '_blank'); } };
注意事项:
- 确保当前用户的access token拥有调用
/auth/login/token的权限(需配置角色权限,至少包含users:read和auth:login权限)。 - 临时令牌有效期不宜过长,避免安全风险。
方案二:共享会话Cookie(同域名场景)
如果React SPA和Directus部署在同一主域名下(例如SPA为app.yourdomain.com,Directus为directus.yourdomain.com),可通过配置Directus的Cookie参数实现会话共享,打开Directus时自动读取会话状态。
实现步骤:
- 配置Directus的Cookie参数
在Directus的.env配置文件中添加以下内容:# 必须设置Directus密钥,用于Cookie加密 KEY=your-directus-secret-key # Directus的公开访问URL PUBLIC_URL=https://directus.yourdomain.com # 设置Cookie的父域名,让子域名共享Cookie COOKIE_DOMAIN=.yourdomain.com # 若使用HTTPS,需开启Secure COOKIE_SECURE=true # SameSite设置为Lax,兼容跨标签页的Cookie传递 COOKIE_SAME_SITE=Lax - SPA中配置凭证携带
调用Directus API时开启withCredentials,确保登录时Cookie被设置到父域名下。以Directus SDK为例:import { createDirectus, authentication } from '@directus/sdk'; const directus = createDirectus('https://directus.yourdomain.com') .with(authentication('cookie', { credentials: 'include' }));
注意事项:
- 仅适用于SPA与Directus同主域名的部署场景,跨域名下浏览器会限制Cookie共享。
- 需确保HTTPS环境(生产环境),否则
COOKIE_SECURE=true会导致Cookie无法设置。
内容的提问来源于stack exchange,提问作者Ranjit Gupta
相关产品推荐
相关产品推荐

