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

使用自定义OAuth提供商Trackmania时NextAuth Session返回null

问题描述

尝试将Trackmania作为自定义OAuth提供商实现身份验证,已成功获取令牌响应,但访问profile页面调用getServerSession时返回的session始终为null,怀疑是next-auth.session-token未正确替换next-auth.state cookie导致。

已完成的操作:

  • 按Trackmania OAuth文档配置流程,登录页使用SignInButton组件触发授权
  • Trackmania OAuth应用已配置好首页与重定向URI
  • 自定义的src/app/api/user/auth-return/route.ts能正常获取令牌,但无法生成有效会话

相关代码配置

NextAuth配置

import type { AuthOptions } from "next-auth";

export const options: AuthOptions = {
  pages: {
    signIn: "/sign-in",
    signOut: "/sign-out"
  },
  providers: [
    {
      id: "trackmania",
      name: "Trackmania",
      type: "oauth",
      wellKnown: "https://api.trackmania.com/.well-known/openid-configuration",
      authorization: {
        params: {
          response_type: "code",
          client_id: process.env.TM_OAUTH_CLIENT_ID,
          scope: "write_favorite",
          redirect_uri: "http://localhost:3000/api/user/auth-return"
        },
        url: "https://api.trackmania.com/oauth/authorize"
      },
      profile(profile, tokens) {
        console.log("profile: ", profile);
        console.log("tokens: ", tokens);
        return {
          ...profile,
          ...tokens
        };
      },
      clientId: process.env.TM_OAUTH_CLIENT_ID,
      clientSecret: process.env.TM_OAUTH_SECRET_ID,
      issuer: "https://api.trackmania.com/",
      token: {
        url: "https://api.trackmania.com/api/access_token"
      },
      userinfo: {
        url: "https://api.trackmania.com/api/user"
      }
    }
  ],
  session: {
    strategy: "jwt"
  }
};

自定义重定向处理路由

import { NextRequest, NextResponse } from "next/server";

export const GET = async (request: NextRequest) => {
  const code = request.nextUrl.searchParams.get("code") || "";
  const url = "https://api.trackmania.com/api/access_token";
  const res = await fetch(url, {
    method: "POST",
    headers: {
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      grant_type: "authorization_code",
      client_id: process.env.TM_OAUTH_CLIENT_ID,
      client_secret: process.env.TM_OAUTH_SECRET_ID,
      code: code,
      redirect_uri: "http://localhost:3000/api/user/auth-return"
    })
  });
  if (!res.ok) {
    const text = await res.text();
    throw new Error(`Failed to fetch data\nStatus: ${res.status}\nResponse: ${text}`);
  }
  const data = await res.json();
  console.log("data: ", data);
  return NextResponse.redirect(new URL("/profile", request.url));
};

Profile页面代码

import { getServerSession } from "next-auth";
import { options } from "../api/auth/[...nextauth]/options";

const ProfilePage = async () => {
  const session = await getServerSession(options);
  console.log("session: ", session);
  return (
    <div className="pl-4">
      <h1 className="text-2xl">ProfilePage</h1>
    </div>
  );
};

.env.local配置

NEXTAUTH_SECRET="ID_GENERATED_FROM_OPENSSL_RAND"
NEXTAUTH_URL="http://localhost:3000/"

TM_OAUTH_CLIENT_ID="..."
TM_OAUTH_SECRET_ID="..."

解决方案

问题核心是你绕过了NextAuth的内置OAuth流程,自定义路由仅获取了令牌,但未让NextAuth处理会话生成和Cookie设置。按以下步骤修复:

  1. 删除自定义的auth-return路由
    完全移除src/app/api/user/auth-return/route.ts,让NextAuth默认回调路由/api/auth/callback/trackmania处理授权响应。

  2. 修正NextAuth配置中的重定向URI
    更新authorization.params.redirect_uri为NextAuth的回调地址:

    authorization: {
      params: {
        response_type: "code",
        client_id: process.env.TM_OAUTH_CLIENT_ID,
        scope: "write_favorite",
        // 修改为NextAuth标准回调地址
        redirect_uri: "http://localhost:3000/api/auth/callback/trackmania"
      },
      url: "https://api.trackmania.com/oauth/authorize"
    },
    
  3. 更新Trackmania OAuth应用的重定向URI
    在Trackmania开发者后台,将重定向URI修改为http://localhost:3000/api/auth/callback/trackmania,确保与NextAuth配置完全一致。

  4. 添加会话同步回调(可选)
    若需要将令牌信息同步到会话,可补充JWT和session回调:

    export const options: AuthOptions = {
      // ...其他配置
      callbacks: {
        async jwt({ token, user, account }) {
          // 首次登录时存入用户和令牌信息
          if (user && account) {
            token.id = user.id;
            token.accessToken = account.access_token;
          }
          return token;
        },
        async session({ session, token }) {
          // 将JWT信息同步到session对象
          session.user.id = token.id;
          session.accessToken = token.accessToken;
          return session;
        }
      }
    };
    
  5. 重启应用测试
    重新启动项目后触发登录流程,NextAuth会自动处理令牌交换、会话生成和Cookie设置,此时getServerSession即可返回有效会话。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 21:19:50