reactjs 请求用户热门曲目和热门艺术家时,Spotify API发出状态代码403

c0vxltue  于 2022-12-26  发布在  React
关注(0)|答案(1)|浏览(111)
  • 更新我可以用艺术家的ID请求艺术家的相册,错误似乎只来自/me端点 *

此处为新开发人员
正在开发一个react应用程序,允许用户登录Spotify,然后显示他们的前10首曲目和前10位艺术家。
我可以登录没有问题,但当我请求用户顶部的曲目和艺术家,我从API得到这样的响应:
加载资源失败:服务器以状态403()响应
下面是App.js:

import WelcomeStatement from './WelcomeStatement';
import LogButton from './LogButton';
import Top10List from './Top10List';

import { useState, useEffect } from 'react';
import axios from 'axios';
import './App.css';
import SpotifyWebApi from 'spotify-web-api-node';

import Box from '@mui/material/Box';

function App() {
  // set auth information
  const CLIENT_ID = '';
  const CLIENT_SECRET =  ''
  const REDIRECT_URI = 'http://localhost:3000';
  const AUTH_ENDPOINT = 'https://accounts.spotify.com/authorize';
  const RESPONSE_TYPE = 'token';
  
  // create a spotify web api instance
  const spotifyNode = new SpotifyWebApi({
    clientId: CLIENT_ID,
    clientSecret: CLIENT_SECRET,
    redirectUri: REDIRECT_URI
  })

  // declare state variables
  const [token, setToken] = useState("");
  const [artists, setArtists] = useState([]);
  const [songs, setSongs] = useState([]);
  const [isLoggedIn, setIsLoggedIn] = useState(false)

  // getter functions for tracks and artists
  const getTracks = function() {
    let res = spotifyNode.getMyTopTracks('limit=10').then(res => console.log(res))
  }

  const getArtists = function() {
    let res = spotifyNode.getMyTopArtists('limit=10').then(res => console.log(res))
  }

  // capture url, trim to just the access token, set token equal to the access token
  // set isLoggedIn state to true and call getter functions
  useEffect(effect => {
    let hash = window.location.hash;
    let token = window.localStorage.getItem('token');

    if (!token && hash){
      token = hash.slice(1).split('&')[0].split('=')[1]
      console.log(token)
      hash = '';
      window.localStorage.setItem('token', token);  
      spotifyNode.setAccessToken(token)
      setIsLoggedIn(true)
      getTracks()
      getArtists()
    }

    setToken(token)
  }, [])

  // set content variable based on isLoggedIn state
  let content = (
    !isLoggedIn ? 
    <>
      <WelcomeStatement isLoggedIn={isLoggedIn}></WelcomeStatement>
      <LogButton isLoggedIn={isLoggedIn} setIsLoggedIn={setIsLoggedIn} setToken={setToken} clientId={CLIENT_ID} redirectUri={REDIRECT_URI} authEndpoint={AUTH_ENDPOINT} responseType={RESPONSE_TYPE}></LogButton>
    </>
    :
    <>
      <WelcomeStatement isLoggedIn={isLoggedIn}></WelcomeStatement>
      <Box className='top-10s-ctr'>
        <Top10List title='Top 10 Artists'></Top10List>
        <Top10List title='Top 10 Songs'></Top10List>
      </Box>
      <LogButton isLoggedIn={isLoggedIn} setIsLoggedIn={setIsLoggedIn} setToken={setToken} clientId={CLIENT_ID} redirectUri={REDIRECT_URI} authEndpoint={AUTH_ENDPOINT} responseType={RESPONSE_TYPE}></LogButton>
    </>
  )

  
  return (
    <Box className="App">
      {content}
    </Box>
  );
}

export default App;

下面是执行授权的LogButton.js:

import './App.css';

import Button from '@mui/material/Button';

export default function LogButton(props) {
    const LOGIN_BUTTON_STYLES = {background: '#1DB954', borderRadius: '30px', p: '15px', fontWeight: 'bold'}

    const logout = () => {
        props.setToken('')
        window.localStorage.removeItem('token')
        props.setIsLoggedIn(false)
      }

    return (
        props.isLoggedIn ?
        <Button
            variant="contained" 
            sx={LOGIN_BUTTON_STYLES}
            onClick={logout}
        >
            Logout
        </Button>
        :
        <Button
            variant="contained" 
            sx={LOGIN_BUTTON_STYLES}
            href={`${props.authEndpoint}?client_id=${props.clientId}&redirect_uri=${props.redirectUri}&response_type=${props.responseType}`}
        >
            Login to Spotify
        </Button>
    )
}

这个账户已经被添加到我的Spotify Jmeter 板上,一开始我以为这是问题所在。
我还尝试用axios.get()fetch()编写请求,它们都有相同的状态代码。
我的授权流程有什么问题吗?或者请求的格式不正确?
泰雅!任何帮助都非常感谢。

ibps3vxo

ibps3vxo1#

我的授权请求中缺少作用域参数。使用/me终结点时,必须定义要代表用户执行的操作。
下面是一个作用域参数的例子:

const SCOPE = 'user-read-private user-read-email user-read-playback-state user-modify-playback-state user-read-recently-played user-top-read';

这里是Spotify's Documentation中的可用范围
快乐编码!

相关问题