You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将会话中的access token插入Next-Auth对接Spotify的API请求头

问题根因

  1. getInitialProps是独立于组件的运行逻辑,作用域内无法读取组件内通过useSession获取的session变量,你直接调用session.user.accessToken会触发未定义报错
  2. 你当前的session回调没有把JWT中存储的accessToken暴露到会话对象中,即便正确拿到session也无法读取token值
  3. JWT回调的参数顺序有误,无法正确在首次授权时捕获Spotify返回的accessToken

修正步骤

1. 调整[...nextauth].js配置

import NextAuth from "next-auth"
import Spotify from "../../../providers/spotify"
import Twitch from "../../../providers/twitch"

export default (req, res) => NextAuth(req, res, {
  providers: [
    Spotify({
      clientId: process.env.SPOTIFY_CLIENT_ID,
      clientSecret: process.env.SPOTIFY_CLIENT_SECRET,
    }),
    Twitch({
      clientId: process.env.TWITCH_CLIENT_ID,
      clientSecret: process.env.TWITCH_CLIENT_SECRET,
    })
  ],
  callbacks: { 
    // 修正参数顺序,首次授权时从account中取token
    async jwt(token, user, account) {
      // 首次登录时把Spotify返回的token存入JWT
      if (account?.accessToken) {
        token.accessToken = account.accessToken
        // 可选:存储refresh token和过期时间,用于后续token刷新
        token.refreshToken = account.refreshToken
        token.expiresAt = account.expires_at * 1000
      }
      return token
    },
    async session(session, token) {
      // 把JWT中的token暴露给session对象
      session.accessToken = token.accessToken
      session.user = token.user || token
      return session
    }
  },
})

2. 调整页面请求逻辑

在getInitialProps中使用getSession方法从请求上下文获取会话,再把token带入请求头:

import axios from "axios";
import { VStack, Heading, Text } from "@chakra-ui/layout";
import { getSession, useSession } from 'next-auth/client'

const Spotify = ({ Spotify, error }) => { 
  const [ session, loading ] = useSession();

  if (loading) return <div>登录校验中...</div>
  if (!session) return <div>请先登录Spotify账号</div>
  if (error) return <div>获取播放列表失败:{error.message}</div>
  if(!Spotify) return <div>加载中...</div>

  return (
    <VStack>
      {Spotify.map((Spoty) => (
          <div key={Spoty.id}>
            <Heading>{Spoty.name}</Heading>
            <Text>链接: {Spoty.href}</Text>
            <Text>创建者: {Spoty.owner.display_name}</Text>
          </div>
        ))}
    </VStack>
  );
};

Spotify.getInitialProps = async (ctx) => {
  // 从请求上下文获取session
  const session = await getSession(ctx)
  if (!session) return { Spotify: null, error: new Error('未登录') }

  try { 
    const res = await axios.get("https://api.spotify.com/v1/me/playlists", { 
      headers: {
        Authorization: `Bearer ${session.accessToken}`
      }
    });
    return { Spotify: res.data.items, error: null };
  } catch (error) {
    return { Spotify: null, error };
  }
};

export default Spotify;

补充说明

如果需要处理Spotify accessToken过期的问题,可以在JWT回调中增加逻辑,当token快过期时用refreshToken换取新的有效token,避免接口请求鉴权失败。

内容的提问来源于stack exchange,提问作者MatDoak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 14:45:04