跨域HttpOnly Cookie配置咨询:本地与生产环境实现方案
我有一个部署在localhost:3000的网站,用户完成登录后,服务器会创建HttpOnly refresh token Cookie,随后用户被重定向至部署在localhost:5000的仪表盘(仪表盘与服务器均部署在localhost:5000)。
需求是让localhost:5000能利用该refresh token生成access token。目前服务器端创建Cookie的配置如下:
res.cookie('token', token, { httpOnly: true, domain: '.localhost', path: '/', maxAge: 1000 * 60 * 60 * 24 * 7, })
localhost:5000的前端用受保护路由包裹所有路由,代码如下:
import { useEffect } from 'react' import styles from './style.module.scss' import { Outlet } from 'react-router-dom' import { useDispatch, useSelector } from 'react-redux' import actions from '../../actions' let isMounted = true function AuthorizationRouter() { const { isAuth, error, user } = useSelector((state) => state.isLoggedIn) const dispatch = useDispatch() useEffect(() => { isMounted && dispatch(actions.users.isUserLoggedIn()) return () => { isMounted = false } }, []) if (error) { console.log('🚀AuthorizationRouter ~ error:', error) window.location.href = 'http://localhost:3000/login' } if (isAuth) { console.log('🚀AuthorizationRouter ~ user:', user) return <Outlet /> } return ( <div className={styles.authorizationRouter}> <div className={styles.container}> <div className={styles.logo}> <img src='/images/light_blue.png' alt='logo' /> </div> <div className={styles.progress}> <div className={styles.progress__bar}> <div className={styles.progress__value}></div> </div> </div> </div> </div> )} export default AuthorizationRouter
当前为开发模式,生产模式下主网站部署在主域名,仪表盘部署在子域名,需实现与开发模式一致的Cookie共享效果。
一、开发环境(localhost跨端口共享Cookie)
浏览器对localhost的Domain处理有特殊逻辑,.localhost这类带前缀的配置多数浏览器不支持,调整如下:
修改服务器端Cookie配置:
移除domain字段,让浏览器默认绑定到localhost(不区分端口),同时设置sameSite属性适配跨端口请求:res.cookie('token', token, { httpOnly: true, path: '/', maxAge: 1000 * 60 * 60 * 24 * 7, sameSite: 'Lax', // 若需跨站请求可设为'None',但None必须配合secure(开发环境http下不能用) })确保前端请求携带Cookie:
前端调用isUserLoggedIn接口时,必须配置请求携带凭证:- 若用axios,给实例添加
withCredentials: true:const api = axios.create({ baseURL: 'http://localhost:5000', withCredentials: true, }) - 若用fetch,设置
credentials: 'include':fetch('/api/isUserLoggedIn', { credentials: 'include', })
这样浏览器会自动将
localhost下的Cookie发送到localhost:5000的服务器,后端就能读取refresh token生成access token。- 若用axios,给实例添加
二、生产环境(主域名与子域名共享Cookie)
假设主站域名为example.com,仪表盘部署在dashboard.example.com,配置如下:
服务器端Cookie配置:
设置domain为.example.com(前缀点匹配所有子域名),同时开启secure(仅HTTPS下生效,生产环境必须):res.cookie('token', token, { httpOnly: true, domain: '.example.com', path: '/', maxAge: 1000 * 60 * 60 * 24 * 7, secure: true, sameSite: 'Lax', // 按需调整为'None'(需配合secure) })前端请求配置:
同开发环境,确保请求携带凭证(axioswithCredentials: true/fetchcredentials: 'include'),浏览器会自动将.example.com的Cookie发送到子域名服务器。
三、核心注意点
- HttpOnly Cookie无法被前端读取:这是安全设计,前端无需直接获取refresh token,由后端接口读取Cookie并生成access token返回。
- SameSite属性:同站场景(主域与子域)用
Lax即可;跨顶级域名场景需设为None,但必须配合secure: true。 - 端口不影响域名匹配:localhost跨端口属于同域名范畴,只要请求携带凭证,浏览器就会自动传递Cookie。
内容的提问来源于stack exchange,提问作者Ahmed Abdelrahman

