我正在开发一个 React 应用程序,它与 Spotify API 集成以进行用户身份验证。 OAuth2 流程似乎按预期工作 — 我被重定向到 Spotify 登录页面,然后返回到我的应用程序。但是,我的应用程序似乎无法识别用户已登录。
问题如下:
尽管 Spotify 的 OAuth2 流程成功,但我的应用程序的状态不会更新以指示用户已登录。 我收到“检测到安全漏洞”错误,表明状态参数不匹配,尽管我对授权 URL 和验证使用相同的状态值。 这是我的应用程序组件的片段:
// App.js (simplified)
useEffect(() => {
const handleHashChange = () => {
handleAuthorization(state, setAccessToken, setLoggedIn);
};
window.addEventListener("hashchange", handleHashChange);
return () => {
window.removeEventListener("hashchange", handleHashChange);
};
}, [state]);
以及 Spotify 授权处理代码:
// Spotify.js (simplified)
export const handleAuthorization = (state, setAccessToken, setLoggedIn) => {
const hash = window.location.hash
.substring(1)
.split("&")
.reduce((initial, item) => {
let parts = item.split("=");
initial[parts[0]] = decodeURIComponent(parts[1]);
return initial;
}, {});
if (hash.state !== state) {
console.error("Security Breach Detected");
}
};
有人遇到过类似的问题或者可以帮助我确定我可能做错了什么吗?
问题源于导航到 Spotify for OAuth 然后返回应用程序时无法保持登录状态。由于跨重定向管理状态的方式,这个问题特别具有挑战性。
解决方案是利用 localStorage 暂时保留状态。这种方法确保即使在重定向到 Spotify 的身份验证页面然后返回到应用程序后,状态仍然保持一致。
以下是对 App.js 和 Spotify.js 文件所做的主要更改:
应用程序.js 在 useEffect 中,检查 localStorage 中是否保存了状态。如果存在,则用它来处理授权。
useEffect(() => {
const savedState = localStorage.getItem('spotify_auth_state');
if (savedState) {
handleAuthorization(savedState, setAccessToken, setLoggedIn);
}
}, []);
Spotify.js 在authorize函数中,将生成的状态保存到localStorage中。
export const authorize = (client_id, redirect_uri) => {
const state = generateRandomString(16);
localStorage.setItem('spotify_auth_state', state); // Save state to localStorage
const url = `https://accounts.spotify.com/authorize?response_type=token&client_id=${client_id}&redirect_uri=${encodeURIComponent(redirect_uri)}&state=${encodeURIComponent(state)}`;
window.location.href = url;
};
在handleAuthorization函数中,将URL哈希中的状态与localStorage中保存的状态进行比较。
export const handleAuthorization = (savedState, setAccessToken, setLoggedIn) => {
// ... existing code ...
if (hash.state !== savedState) {
console.error('Security Breach Detected');
setLoggedIn(false);
setAccessToken('');
}
localStorage.removeItem('spotify_auth_state'); // Remove state after it's used
};
通过使用 localStorage 来持久化状态,我们可以有效地跨页面重定向维护登录状态。
您可以在此 GitHub Gist 中找到完整的代码。
希望这可以帮助任何面临类似问题的人!