OAuth 2.0 Spotify 内部OAuthError

问题描述 投票:0回答:1
InternalOAuthError: failed to fetch user profile
    at C:\Users\PAKSHAL\Documents\Pakshal\Projects\Saarang\backend\node_modules\passport-spotify\lib\passport-spotify\strategy.js:151:19
    at passBackControl (C:\Users\PAKSHAL\Documents\Pakshal\Projects\Saarang\backend\node_modules\passport-oauth2\node_modules\oauth\lib\oauth2.js:132:9)
    at IncomingMessage.<anonymous> (C:\Users\PAKSHAL\Documents\Pakshal\Projects\Saarang\backend\node_modules\passport-oauth2\node_modules\oauth\lib\oauth2.js:157:7)
    at IncomingMessage.emit (node:events:531:35)
    at endReadableNT (node:internal/streams/readable:1696:12)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21)

刷新页面后消息发生更改:

TokenError: Invalid authorization code
    at OAuth2Strategy.parseErrorResponse (C:\Users\PAKSHAL\Documents\Pakshal\Projects\Saarang\backend\node_modules\passport-oauth2\lib\strategy.js:373:12)
    at OAuth2Strategy._createOAuthError (C:\Users\PAKSHAL\Documents\Pakshal\Projects\Saarang\backend\node_modules\passport-oauth2\lib\strategy.js:420:16)
    at C:\Users\PAKSHAL\Documents\Pakshal\Projects\Saarang\backend\node_modules\passport-oauth2\lib\strategy.js:177:45
    at C:\Users\PAKSHAL\Documents\Pakshal\Projects\Saarang\backend\node_modules\passport-spotify\lib\passport-spotify\strategy.js:81:20
    at passBackControl (C:\Users\PAKSHAL\Documents\Pakshal\Projects\Saarang\backend\node_modules\passport-oauth2\node_modules\oauth\lib\oauth2.js:132:9)
    at IncomingMessage.<anonymous> (C:\Users\PAKSHAL\Documents\Pakshal\Projects\Saarang\backend\node_modules\passport-oauth2\node_modules\oauth\lib\oauth2.js:157:7)
    at IncomingMessage.emit (node:events:531:35)
    at endReadableNT (node:internal/streams/readable:1696:12)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21)
  • 这种情况发生在不同的用户身上,我尝试了三个用户,其中两个用户遇到这个问题,一个用户没有遇到这个问题。

  • '/' -> 你好世界

  • '/auth/spotify' -> 'auth/spotify/callback' -> 输入凭据

  • '/dashboard' -> 欢迎,用户名

    我列出了这两个错误,而不是上面使用正确凭据登录时接收用户名的输出。
    我正在使用 Oauth 2.0 Spotify 登录我的应用程序,我在 Spotify 仪表板中创建了应用程序,获取了客户端凭据、密钥并输入了正确的回调 URI,使用了 Passport-spotify。
    这就是我正在做的:

  • 索引.js

    const express = require('express');
    const mongoose = require('mongoose');
    const passport = require('passport');
    const session = require('express-session');
    const authRoutes = require('./routes/auth');
    const groupRoutes = require('./routes/grouproutes');
    require('dotenv').config();
    require('./config/passport');  // Initialize passport strategy
    const cors = require('cors');
    
    const app = express();
    
    app.use(cors());
    app.use(express.json());
    // Middleware for session management
    app.use(session({
      secret: process.env.SESSION_SECRET,
      resave: false,
      saveUninitialized: true
    }));
    
    // Passport middleware
    app.use(passport.initialize());
    app.use(passport.session());
    
    // MongoDB connection
    mongoose.connect(process.env.MONGO_URI)
      .then(() => console.log('MongoDB connected'))
      .catch(err => console.error('MongoDB connection error:', err));
    
    // Auth routes
    app.use('/auth', authRoutes);
    app.use('/group',groupRoutes);
    
    app.listen(process.env.PORT || 3000, () => {
      console.log(`Server running on port ${process.env.PORT || 3000}`);
      app.get('/', (req, res) => {
        res.send('Hello, world!');
      });
    });
    
    
    app.get('/dashboard', (req, res) => {
      if (!req.isAuthenticated()) {
        return res.redirect('/auth/spotify');
      }
      res.send(`Welcome, ${req.user.displayName}!`);  // Access user info from Spotify profile
    });
    
    
  • Passport.js

    const passport = require('passport');
    const SpotifyStrategy = require('passport-spotify').Strategy;
    const User = require('../models/User');  // Your User model
    
    passport.use(new SpotifyStrategy({
      clientID: process.env.SPOTIFY_CLIENT_ID,
      clientSecret: process.env.SPOTIFY_CLIENT_SECRET,
      callbackURL: "http://localhost:3000/auth/spotify/callback",
    },
      async function(accessToken, refreshToken, expires_in, profile, done) {
        try {
          // Check if the user already exists
          let user = await User.findOne({ spotifyId: profile.id });
    
          if (!user) {
            // If user doesn't exist, create a new one
            user = new User({
              spotifyId: profile.id,
              displayName: profile.displayName,
              email: profile.emails[0].value,
              profileImage: profile.photos[0]?.value,
              accessToken,
              refreshToken
            });
            await user.save();
          } else {
            // If user exists, update tokens
            user.accessToken = accessToken;
            user.refreshToken = refreshToken;
            await user.save();
          }
    
          return done(null, user);
        } catch (err) {
          return done(err, null);
        }
      }
    ));
    
    passport.serializeUser((user, done) => {
      done(null, user.id);
    });
    
    passport.deserializeUser(async (id, done) => {
      try {
        const user = await User.findById(id);
        done(null, user);
      } catch (err) {
        done(err, null);
      }
    });
    
    
  • authmiddleware.js

    const axios = require('axios');
    const User = require('../models/User');
    
    const ensureAuthenticated = async (req, res, next) => {
      const authHeader = req.headers.authorization;
    
      if (!authHeader || !authHeader.startsWith('Bearer ')) {
        return res.status(401).json({ message: 'User not authenticated' });
      }
    
      const token = authHeader.split(' ')[1];
    
      try {
        // Validate the token by making a request to Spotify API
        const response = await axios.get('https://api.spotify.com/v1/me', {
          headers: {
            Authorization: `Bearer ${token}`,
          },
        });
    
        const spotifyUserData = response.data;
    
        // Find the user in your MongoDB by spotifyId
        const user = await User.findOne({ spotifyId: spotifyUserData.id });
    
        if (!user) {
          return res.status(401).json({ message: 'User not found in the system' });
        }
    
        // Attach MongoDB user object to req.user
        req.user = user;
    
        next(); // Continue to the next middleware or route handler
      } catch (error) {
        return res.status(401).json({ message: 'Invalid token or session expired' });
      }
    };
    
    module.exports = ensureAuthenticated;
    
    
  • User.js(模型)

    const mongoose = require('mongoose');
    
    const userSchema = new mongoose.Schema({
      spotifyId: { type: String, required: true, unique: true }, // Spotify ID
      displayName: { type: String },  // Spotify username
      email: { type: String },        // Spotify email
      profileImage: { type: String }, // Spotify profile picture
      accessToken: { type: String },  // Spotify OAuth access token
      refreshToken: { type: String }, // Spotify OAuth refresh token
      friends: [{ type: mongoose.Schema.Types.ObjectId, ref: 'User' }], // Friends in your app
      friendRequests: [{ type: mongoose.Schema.Types.ObjectId, ref: 'User' }], // Pending friend requests
      activeGroup: { type: mongoose.Schema.Types.ObjectId, ref: 'Group', default: null },  // Active group, null if not in any
      createdAt: { type: Date, default: Date.now }
    });
    
    module.exports = mongoose.model('User', userSchema);
    
    
javascript oauth-2.0 passport.js
1个回答
0
投票

事实证明这是一个愚蠢的错误,我为此浪费了两天时间, 原因: 我的 Spotify 应用程序处于开发人员模式,因此对于我尝试注册的任何用户,我应该首先转到 Spotify 仪表板 -> 单击应用程序 -> 设置 -> 用户管理 -> 手动添加用户以访问您的应用程序进行测试。 当您准备好部署时,请进入设置 -> 扩展请求 -> 提交扩展请求! 干杯!这就是为什么总是阅读文档!!

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