简体   繁体   English

如何在服务器端使用 SvelteKit 获取 Auth0 中的用户详细信息

[英]How can I get the user details in Auth0 using SvelteKit on the server side

I am trying to authenticate a user with Auth0 service using SvelteKit, on the server side but keep getting the error invalid_token , cannot read properties of undefined :我正在尝试在服务器端使用 SvelteKit 使用 Auth0 服务对用户进行身份验证,但不断收到错误invalid_token , cannot read properties of undefined

outer {
  error: 'invalid_token',
  errorDescription: "Cannot read properties of undefined (reading 'XMLHttpRequest')"
}

The login endpoint:登录端点:

import * as auth0 from "auth0-js";

/** @type {import('@sveltejs/kit').RequestHandler} */
export async function post({ request }) {

        const body = await request.json();
        const hash = body.hash;
        console.log("Sign-in.ts", hash);

        // Initialize the Auth0 application
        var webAuth = new auth0.WebAuth({
            domain: '<domain>',
            clientID: '>clientid>'
        });
        // Parse the URL and extract the Access Token
        webAuth.parseHash({hash: hash, state: "rtre4", nonce: "er324"}, function (err, authResult) {
            if (err) {
                return console.log("outer", err);
            }
            
            webAuth.client.userInfo(authResult.accessToken, function (innerErr, user) {
                // This method will make a request to the /userinfo endpoint
                // and return the user object, which contains the user's information,
                // similar to the response below.
                if (innerErr) {
                    return console.log("inner", innerErr);
                    
                }

                console.log(user);
            });
        });

        return {
            status: 200,
            body: {
                message: "OK"
            }
        };
};

I can successfully log the user in and redirect the user to my /login route with the access and id tokens as hash in the url. Next I am trying to get the user details.我可以成功登录用户并将用户重定向到我的 /login 路由,访问和 ID 令牌为 url 中的 hash。接下来我试图获取用户详细信息。 I want to get the user details in the server, so I send the complete hash to my /api/login.ts endpoint with a POST request, and call the auth0-js function parseHash in the server endpoint, which fails.我想在服务器中获取用户详细信息,因此我通过POST请求将完整的 hash 发送到我的/api/login.ts端点,并在服务器端点中调用auth0-js function parseHash ,但失败了。 The same code works on the client-side, though.不过,相同的代码适用于客户端。

The landing page:着陆页:

<script lang="ts">
    import { onMount } from 'svelte';

    onMount(async () => {
        const hash = window.location.hash;
        const response = await fetch("/api/sign-in", {
                method: "POST",
                headers: {
                    "Content-Type": "application/json"
                },
                body: JSON.stringify({
                    hash: hash
                })
            });
            console.log(response);
    });
</script>
<div class="content">
    <p>Redirecting, please wait...</p>
</div>

Therefore I am thinking either the cookie somehow changes during stringifying it, or Sveltekit does not have XmlHttpRequest, but does anyone has further insight?因此我在想,要么 cookie 在对其进行字符串化过程中以某种方式发生了变化,要么 Sveltekit 没有 XmlHttpRequest,但是有人有进一步的见解吗?

If you have a JWT token in your cookies you can decode the JWT cookie to get the user information You can do that like this:如果您的 cookies 中有一个 JWT 令牌,您可以解码 JWT cookie 以获取用户信息,您可以这样做:

import * as cookie from 'cookie';
import Buffer from 'buffer';
export const handle = async ({ event, resolve }) => {

    const cookies = cookie.parse(event.request.headers.get('cookie') || '');
    if(!cookies.id_token) {
       
        return await resolve(event);
    }
    
    const base64Payload = cookies.id_token.split('.')[1];
    const decodedJWTToken = base64Payload ? Buffer.Buffer.from(base64Payload, 'base64') : '';
    event.locals.user = decodedJWTToken ? JSON.parse(decodedJWTToken.toString()) : null

    const response =  await resolve(event);
    return response

};

export function getSession({ locals }) {
    return {
        user: locals.user && {
            nickname: locals.user.nickname ? locals.user.nickname : null,
            email: locals.user.email ? locals.user.email : null,
            sub: locals.user.sub ? locals.user.sub : null,
            email_verified: locals.user.email_verified ? locals.user.email_verified : null,
            picture: locals.user.picture ? locals.user.picture : null,
        }
    };
}

Thanks to Andreas's comments, I realized that XmlHttpRequest is a browser feature that does not exist in a server.感谢 Andreas 的评论,我意识到XmlHttpRequest是服务器中不存在的浏览器功能。 For this reason, I have implemented a manual request to the Auth0 endpoint using the token I get from the page to get the user details:出于这个原因,我使用从页面获取的令牌实现了对 Auth0 端点的手动请求以获取用户详细信息:

/** @type {import('@sveltejs/kit').RequestHandler} */
export async function post({ request }) {

    /**
     * auth0.WebAuth does not work on server side because it uses XmlHttpRequest, which is unavailable on server
     */
        const body = await request.json();
        const token = body.accessToken;
        const response = await fetch("https://<app Auth0 address>/userinfo", {
            method: "GET",
            headers: { 
                "Content-Type":"application/json",
                "Authorization": `Bearer ${token}`},
        });

        const userData = await response.json();
        console.log(userData);
        };
};

I am still calling the method webAuth.parseHash in the client-side where auth0.js works, because this method also validates the tokens automatically.我仍然在 auth0.js 工作的客户端调用方法webAuth.parseHash ,因为这个方法也会自动验证令牌。 After validation, I am POST ing the access token to the endpoint.验证后,我将访问令牌POST到端点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在 getServerSideProps 中获取 Auth0 User 对象? - How to get Auth0 User object in getServerSideProps? 如何为自定义Auth0登录表单实现服务器端代码? - How do I implement server-side code for a custom Auth0 login form? 如何使用@auth0/auth0-react 启动注册页面? - How can I launch the registration page using @auth0/auth0-react? 我如何使用 firebase auth 在 nodejs 的服务器端验证用户电话号码 - How can i authenticate user phone number on server side in nodejs with firebase auth 如何在 React 中从 auth0 获取用户 ID - How to get user's id from auth0 in React 如何使用 Auth0 和带有 MERN 应用程序的护照获取附加到 req object 的 session 属性? - How do I get the session property appended to the req object using Auth0 and passport with a MERN app? 如何使用 lock v11 从 auth0 无密码获取刷新令牌? - How do I get a refresh token from auth0 passwordless using lock v11? 在NestJS中获取Auth0用户信息 - Get Auth0 user info in NestJS 如何使用Auth0 Lock从响应对象获取用户名? - How to get a username from response object using Auth0 Lock? 如何在 VueJS 中使用 Auth0 对 apollo 进行身份验证 - How can I authenticate apollo with Auth0 in VueJS
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM