mcy
mcy

Reputation: 1258

Auth0 Server Side Authentication with SvelteKit

I know there is no official Auth0 SvelteKit plugin for direct use, so I am trying to implement a manual approach using basic API functions in JS for server side authentication and session management, using auth0.js version 9.11.

Using the following page, I can redirect the user to the Auth0 universal login page, and the user is redirected to my landing page after a successful login. My plan is to acquire the user details from the user token on the page then send these details to a server endpoint. In the endpoint I will save these details to a database (with the access token) for login session management, then send a HttpOnly cookie for auth guards..etc.

However, I keep getting the following error within the landing page:

Uncaught (in promise) TypeError: can't assign to property "__enableIdPInitiatedLogin" on "#access_token=eyJhbGciOi...<very long token>...BNW1uzA&scope=openid%20profile%20email&expires_in=7200&token_type=Bearer&state=rtre4": not an object

The code that is used to fetch user details and doesn't work is as follows:

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

    onMount(async () => {
        // Initialize the Auth0 application
        var webAuth = new auth0.WebAuth({
            domain: '<domain>',
            clientID: '<clientId>'
        });
        //test
        console.log(window.location.hash);
        // Parse the URL and extract the Access Token
        webAuth.parseHash(window.location.hash, function (err, authResult) {
            if (err) {
                return console.log(err);
            }
            // webAuth.client.userInfo(authResult.accessToken, function (err, 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.
            // });
        });
    });
</script>

<svelte:head>
    <script src="https://cdn.auth0.com/js/auth0/9.11/auth0.min.js"></script>
</svelte:head>
<div class="content">
    <p>Redirecting, please wait...</p>
</div>

The code that redirects the user to the universal login page is as follows:

<script lang="ts">

    import Button from '@smui/button';

    const login = () => {
        // Initialize app - auth0 is defined as external script in <svelte:head>
            var webAuth = new auth0.WebAuth({
            domain: '<domain>,
            clientID: '<clientid>'
        });

        // Calculate URL to redirect to
        var url = webAuth.client.buildAuthorizeUrl({
            clientID: '<clientid>', // string
            responseType: 'token id_token', // code or token
            redirectUri: 'http://localhost:3000/login',
            scope: 'openid profile email',
            state: '<state>',
            nonce: '<nonce>'

        });

        window.location = url;
    }
</script>

<svelte:head>
    <script src="https://cdn.auth0.com/js/auth0/9.11/auth0.min.js"></script>
</svelte:head>

<div class="content">
    <Button on:click={login}>Login</Button>
    
</div>

EDIT I have added the id_token to the login url construction (which also requires nonce parameter) based on Kalana's comment and modified the error screenshot based on the new code.

Upvotes: 1

Views: 1754

Answers (1)

mcy
mcy

Reputation: 1258

After some more digging, I have realized that the options supplied to the parseHash function needs to be a JSON object. You also need to have id_token in the creation of login request (thanks to the comment by Kalana), and a nonce parameter as well. You have to give the same state and nonce values to the parseHash function, too. Additionally, the hash for this function is optional; if none is given it can get it from windows.location.hash automatically.

In the end, the working code for fetching the user information from Auth0 service is as follows:

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

    onMount(async () => {
        // Initialize the Auth0 application
        var webAuth = new auth0.WebAuth({
            domain: '<domain>',
            clientID: '<clientid>'
        });
        
        // Parse the URL and extract the Access Token
        webAuth.parseHash({state: "<sameState>", nonce: "<sameNonce>"}, function (err, authResult) {
            if (err) {
                return console.log(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(innerErr);
                    
                }
                console.log(user);
            });
        });
    });
</script>

<svelte:head>
    <script src="https://cdn.auth0.com/js/auth0/9.11/auth0.min.js"></script>
</svelte:head>
<div class="content">
    <p>Redirecting, please wait...</p>
</div>

Upvotes: 1

Related Questions