Search code examples
javascriptxmlhttprequestauth0sveltekit

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:

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. 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. 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?


Solution

  • Thanks to Andreas's comments, I realized that XmlHttpRequest is a browser feature that does not exist in a server. 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:

    /** @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. After validation, I am POSTing the access token to the endpoint.