调用Express OAuth接口后重定向失效,React实现TikTok授权跳转失败
问题根源
你遇到的报错本质是两个原因叠加导致的:
fetch属于AJAX异步请求,默认遵循同源策略,当你的Express接口返回302重定向到TikTok域名时,浏览器会自动尝试向TikTok地址发起AJAX请求,而TikTok的开放接口没有配置允许你本地域名跨域访问,直接触发CORS拦截。- 即使没有CORS限制,
fetch本身也不会触发浏览器的整页跳转行为,你拿到重定向响应后也不会自动跳到TikTok登录页,不符合OAuth授权流程的设计逻辑。
OAuth授权码流程的设计本身就要求浏览器整页跳转到第三方授权平台的页面,不应该用AJAX请求授权入口。
解决方案
方案1:最简修改(推荐)
直接把前端的fetch请求替换为浏览器整页跳转即可,不需要改后端代码,修改前端登录按钮的点击逻辑:
const TiktokLogin = ({ cssClass }) => { const handleClick = (e) => { e.preventDefault() // 直接跳转至后端/oauth接口,浏览器会自动跟随302重定向到TikTok授权页 window.location.href = '/oauth' }; return ( <button type="button" className={cssClass} onClick={handleClick}> Identify me with <i className="fab fa-tiktok" /> </button> ); };
你也可以直接用<a>标签代替按钮,设置href="/oauth",样式调整成按钮样式即可,效果完全一致。
方案2:前后端配合修改(适合需要前置处理逻辑的场景)
如果你需要在跳转前做额外的前端逻辑(比如埋点统计、权限校验等),可以修改后端接口不返回重定向,而是将TikTok授权链接返回给前端,前端拿到后手动跳转:
后端修改:
app.get("/oauth", (req, res) => { const csrfState = Math.random().toString(36).substring(7); res.cookie("csrfState", csrfState, { maxAge: 60000 }); let url = "https://open-api.tiktok.com/platform/oauth/connect/"; url += `?client_key=${CLIENT_KEY}`; url += "&scope=user.info.basic,video.list"; url += "&response_type=code"; url += `&redirect_uri=${REDIRECT_URI}`; url += `&state=${csrfState}`; // 不再返回重定向,而是返回授权链接 res.json({ authUrl: url }); });
前端修改:
const TiktokLogin = ({ cssClass }) => { const handleClick = async (e) => { e.preventDefault() const res = await fetch("/oauth") const { authUrl } = await res.json() // 手动跳转到TikTok授权页 window.location.href = authUrl }; return ( <button type="button" className={cssClass} onClick={handleClick}> Identify me with <i className="fab fa-tiktok" /> </button> ); };
两种方案都可以解决CORS报错,同时实现跳转TikTok授权页的需求,推荐优先使用方案1,改动最小且完全符合OAuth标准流程。
内容的提问来源于stack exchange,提问作者Bonsai Noodle
相关产品推荐
相关产品推荐

