React 应用程序无法检测到使用 Spotify API 成功进行 OAuth2 登录

问题描述 投票:0回答:1

我正在开发一个 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");
  }
};

有人遇到过类似的问题或者可以帮助我确定我可能做错了什么吗?

javascript reactjs spotify
1个回答
0
投票

问题源于导航到 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 中找到完整的代码。

希望这可以帮助任何面临类似问题的人!

© www.soinside.com 2019 - 2024. All rights reserved.