我正在尝试通过我的烧瓶后端中的spotipy 来验证用户身份验证,该后端是独立工作的。但是,当我尝试引入前端组件时,后端似乎没有发送正确的信息,或者前端获取了错误的信息。我尝试确保我从后端正确发送 cookie,并且我的缓存没有被用来记住用户是否登录。我对 Web 开发非常陌生,尤其是前端,所以任何帮助将不胜感激。
这是我期望我的代码发生的事情
这是我后端的相关代码:
@app.route('/')
def index():
cache_handler = spotipy.cache_handler.FlaskSessionCacheHandler(session)
auth_manager = spotipy.oauth2.SpotifyOAuth(client_id=CLIENT_ID, client_secret=CLIENT_SECRET, redirect_uri=REDIRECT_URI, scope='user-read-currently-playing',
cache_handler=cache_handler)
if not auth_manager.validate_token(cache_handler.get_cached_token()):
auth_url = auth_manager.get_authorize_url()
#print(auth_url)
return jsonify({"logged_in": False, "auth_url": auth_url})
spotify = spotipy.Spotify(auth_manager=auth_manager)
user_info = spotify.me()
return jsonify({
"logged_in": True,
"user_info": {
"display_name": user_info["display_name"],
"id": user_info["id"],
"uri": user_info["uri"],
"profile_url": user_info["external_urls"]["spotify"]
}
})
@app.route('/callback')
def callback():
code = request.args.get('code')
print(code)
if code:
cache_handler = spotipy.cache_handler.FlaskSessionCacheHandler(session)
auth_manager = spotipy.oauth2.SpotifyOAuth(client_id=CLIENT_ID, client_secret=CLIENT_SECRET, redirect_uri=REDIRECT_URI, scope='user-read-currently-playing',
cache_handler=cache_handler)
auth_manager.get_access_token(code)
session.modified = True
response = make_response(redirect('http://localhost:3000/'))
return response
return 'Missing code parameter. Please try again.', 400
这是我的前端 App.js:
function App() {
const [message, setMessage] = useState('');
const [isLoggedIn, setIsLoggedIn] = useState(false);
const [authUrl, setAuthUrl] = useState('');
useEffect(() => {
const url = `http://127.0.0.1:5000/?t=${Date.now()}`;
axios.get(url, { withCredentials: true })
.then(response => {
const { logged_in, auth_url } = response.data;
console.log(response.data);
setIsLoggedIn(logged_in);
if (!logged_in) {
setAuthUrl(auth_url);
console.log('Redirecting to:', auth_url);
}
})
.catch(error => console.error('Error:', error));
}, []);
return (
<Router>
<div className="App">
<div className="App-header">
<Routes>
<Route path="/login" element={!isLoggedIn ? <Login authUrl={authUrl} /> : <Navigate to="/" />} /> // Use the Login component here
<Route path="/" element={isLoggedIn ? <SearchBar onSearch={setMessage} /> : <Navigate to="/login" />} />
</Routes>
</div>
</div>
</Router>
);
}
export default App;
我做了一些测试,在回调函数中,如果我重定向回 localhost:5000,它会向我显示以下数据:
"logged_in": True,
"user_info": { etc etc...
这就是我希望前端检测到的内容。但由于某种原因,它仍然将 Logged_in 视为 false。
当使用
spotipy
进行授权代码流程时,您不一定需要自己通过重定向来处理回调端点。
Spotipy
支持Spotify提供的多种身份验证流程,包括授权代码流程。
当
Spotipy
被描述为授权代码流的中间件时,这意味着 Spotipy
可以在 Python 应用程序中无缝处理大部分身份验证过程。
Spotipy 是中间件。 所以你不需要处理
./callback
端点。
后端服务器由
Flask
import spotipy
from flask import Flask, session, jsonify
from flask_cookie_decode import CookieDecode
from spotipy.oauth2 import SpotifyOAuth
from flask_cors import CORS, cross_origin
CLIENT_ID = '<your client id>'
CLIENT_SECRET = '<your client secret>'
REDIRECT_URI = '<your redirect uri>' # get from developer dash board
username = '<your Spotify User id>' # get from user profile
SCOPEs = ['user-read-currently-playing', 'user-read-recently-played']
# Create the Flask application
app = Flask(__name__)
cors = CORS(app)
app.config['CORS_HEADERS'] = 'Content-Type'
app.config.update({'SECRET_KEY': 'MY_SECRET_KEY'})
cookie = CookieDecode()
cookie.init_app(app)
cache_handler = spotipy.cache_handler.FlaskSessionCacheHandler(session)
auth_manager = SpotifyOAuth(client_id=CLIENT_ID,
client_secret=CLIENT_SECRET,
redirect_uri=REDIRECT_URI,
scope=SCOPEs,
username=username,
cache_handler=cache_handler)
auth_url = auth_manager.get_authorize_url()
@app.route('/get_logged')
@cross_origin()
def get_session():
if (session and session['user']):
return jsonify(dict(session))
else:
return jsonify({'logged_in': False, 'auth_url': auth_url})
@app.route('/clear_session')
@cross_origin()
def clear_session():
session.clear()
return jsonify({'session': 'cleared'})
@app.route('/login')
@cross_origin()
def login():
auth_manager = SpotifyOAuth(client_id=CLIENT_ID,
client_secret=CLIENT_SECRET,
redirect_uri=REDIRECT_URI,
scope=SCOPEs,
username=username)
if (session and session['user']):
data = jsonify(dict(session).get('user')['user_info'])
return data
sp = spotipy.Spotify(auth_manager=auth_manager)
user_info = sp.me()
simple_user_info = {
"logged_in": True,
"user_info": {
"display_name": user_info["display_name"],
"id": user_info["id"],
"uri": user_info["uri"],
"profile_url": user_info["external_urls"]["spotify"]
}
}
session['user'] = simple_user_info
return jsonify(dict(session).get('user'))
if __name__ == '__main__':
app.run()
清除会话
GET http://localhost:5000/clear_session
登录
GET http://localhost:5000/get_logged
登录
GET http://localhost:5000/login
注意- 此 API 只能由 React 调用
应用程序.js
import React, { useState } from 'react';
import axios from 'axios';
function App() {
const [loggedIn, setLoggedIn] = useState(false);
const [userData, setUserData] = useState(null);
const handleLogin = async () => {
try {
const response = await axios.get('http://localhost:5000/login'); // Update URL if needed
setUserData(response.data);
setLoggedIn(true);
} catch (error) {
console.error('Error logging in:', error);
}
};
return (
<div>
{loggedIn ? (
<div>
<h1>Welcome, {userData?.user_info?.display_name}</h1>
<p>ID: {userData?.user_info?.id}</p>
<p>URI: {userData?.user_info?.uri}</p>
<a href={userData?.user_info?.profile_url}>Profile Link</a>
</div>
) : (
<div>
<h1>Not logged in</h1>
<button onClick={handleLogin}>Login with Spotify</button>
</div>
)}
</div>
);
}
export default App;
http://localhost:3000/