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

在SvelteKit服务器端使用Auth0认证并获取用户详情时遭遇invalid_token错误的技术问询

问题根源分析

你遇到的invalid_token错误附带的Cannot read properties of undefined (reading 'XMLHttpRequest')提示,其实已经点明了核心问题:auth0-js是专门为浏览器环境设计的客户端库,它依赖浏览器特有的API(比如XMLHttpRequest、window对象),而SvelteKit的服务器端运行在Node.js环境中,没有这些浏览器API,所以直接调用会报错。

webAuth.parseHash和webAuth.client.userInfo这两个方法都是为浏览器场景设计的:parseHash用来解析浏览器URL中的哈希参数,userInfo内部用XMLHttpRequest发送请求,这些在服务器端都无法正常工作。

解决方案:改用服务器端兼容的Auth0工具

我们需要替换掉客户端的auth0-js,改用Auth0提供的Node.js SDK,或者直接调用Auth0的REST API,这些都是为服务器端环境设计的。下面分步骤给出具体实现:

1. 优化客户端代码:提前解析哈希提取令牌

与其把整个哈希字符串发给服务器,不如在客户端先解析出需要的令牌(比如access_token或id_token),这样更高效,也减少服务器端的处理负担:

<script lang="ts">
 import { onMount } from 'svelte';
 onMount(async () => {
   // 解析URL哈希中的参数
   const hashParams = new URLSearchParams(window.location.hash.slice(1));
   const accessToken = hashParams.get('access_token');
   const idToken = hashParams.get('id_token');

   if (accessToken) {
     const response = await fetch("/api/sign-in", {
       method: "POST",
       headers: { "Content-Type": "application/json" },
       // 只发送需要的令牌,而不是整个哈希
       body: JSON.stringify({ accessToken, idToken })
     });
     const result = await response.json();
     console.log('Server response:', result);
   }
 });
</script>
<div class="content">
 <p>Redirecting, please wait...</p>
</div>

2. 改造服务器端端点:使用服务器端方式获取用户信息

方式一:直接调用Auth0的/userinfo REST API

这种方式不需要额外安装SDK,用Node.js原生的fetch即可(SvelteKit服务器端支持fetch):

import { env } from '$env/dynamic/private';

/** @type {import('@sveltejs/kit').RequestHandler} */
export async function post({ request }) {
 const { accessToken } = await request.json();

 try {
   // 调用Auth0的userinfo端点获取用户信息
   const userInfoResponse = await fetch(`https://${env.AUTH0_DOMAIN}/userinfo`, {
     headers: {
       'Authorization': `Bearer ${accessToken}`
     }
   });

   if (!userInfoResponse.ok) {
     throw new Error('Invalid or expired access token');
   }

   const user = await userInfoResponse.json();
   console.log('Fetched user info:', user);

   return {
     status: 200,
     body: { user, message: 'Success' }
   };
 } catch (err) {
   console.error('Error during authentication:', err);
   return {
     status: 401,
     body: { error: 'invalid_token', errorDescription: err.message }
   };
 }
};

方式二:使用Auth0 Node.js SDK(更便捷)

如果需要更丰富的服务器端操作(比如管理用户、角色等),可以安装官方的Node.js SDK:

首先安装依赖:

npm install auth0

然后修改端点代码:

import { ManagementClient } from 'auth0';
import { env } from '$env/dynamic/private';

/** @type {import('@sveltejs/kit').RequestHandler} */
export async function post({ request }) {
 const { accessToken } = await request.json();

 try {
   // 初始化Auth0管理客户端
   const managementClient = new ManagementClient({
     domain: env.AUTH0_DOMAIN,
     clientId: env.AUTH0_CLIENT_ID,
     clientSecret: env.AUTH0_CLIENT_SECRET, // 从环境变量读取,不要硬编码
     token: accessToken // 使用用户的access_token访问userinfo
   });

   // 获取当前令牌对应的用户信息
   const user = await managementClient.getUser({ id: 'me' });
   console.log('Fetched user info:', user);

   return {
     status: 200,
     body: { user, message: 'Success' }
   };
 } catch (err) {
   console.error('Error during authentication:', err);
   return {
     status: 401,
     body: { error: 'invalid_token', errorDescription: err.message }
   };
 }
};

3. 关键安全提示:验证令牌有效性

无论用哪种方式,服务器端都应该验证令牌的合法性,确保它是Auth0签发、未过期、受众正确的。对于id_token,可以用jsonwebtoken库结合Auth0的公钥来验证签名:

安装依赖:

npm install jsonwebtoken jwks-rsa

添加验证逻辑:

import jwt from 'jsonwebtoken';
import jwksClient from 'jwks-rsa';
import { env } from '$env/dynamic/private';

// 初始化JWKS客户端,用于获取Auth0的公钥
const jwksClientInstance = jwksClient({
  jwksUri: `https://${env.AUTH0_DOMAIN}/.well-known/jwks.json`
});

// 获取签名公钥的辅助函数
function getSigningKey(header, callback) {
  jwksClientInstance.getSigningKey(header.kid, (err, key) => {
    if (err) return callback(err);
    const signingKey = key.getPublicKey();
    callback(null, signingKey);
  });
}

// 在post处理函数中验证id_token
const { idToken } = await request.json();
jwt.verify(idToken, getSigningKey, {
  audience: env.AUTH0_CLIENT_ID,
  issuer: `https://${env.AUTH0_DOMAIN}/`,
  algorithms: ['RS256']
}, (err, decodedToken) => {
  if (err) {
    console.error('Invalid ID token:', err);
    return { status: 401 };
  }
  // decodedToken中包含用户的核心信息
  console.log('Verified user:', decodedToken);
});
总结

核心问题就是误用了客户端库在服务器端环境,只要替换为服务器端兼容的Auth0工具,就能解决XMLHttpRequest未定义的错误,同时也能更安全地完成用户认证流程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 17:18:11