Quantcast
Channel: Active questions tagged svelte - Stack Overflow
Viewing all articles
Browse latest Browse all 1541

Supabase Auth exchangeCodeForSession returns "invalid request: both auth code and code verifier should be non-empty"

$
0
0

Architecture:

This is Cross-Platform web-based (SEO focused) project, that was built in CSR due to bad performance using SSR w/ Capacitor framework.

Client: Svelte + Vite + Capacitor

Due to use of vanilla Svelte, to handle navigation our choice was "svelte-routing", for building the app on both web and mobile (iOS and Android) we use Capacitor.

Server: Fastify + Supabase

Our server framework of choice was Fastify, as long w/ Supabase, and thus we need to use the Supabase Auth solutions, what prevent us from using tools like Capacitor Generic OAuth2.


Problem

Following the Supabase guide to implement Google OAuth2, when storing the user session, got an AuthApiError: "invalid request: both auth code and code verifier should be non-empty"


Packages:

// package.json{    ...,"dependencies": {"@fastify/compress": "^8.0.1","@fastify/cookie": "^11.0.2","@fastify/cors": "^10.0.2","@fastify/env": "^5.0.2","@fastify/formbody": "^8.0.2","@fastify/multipart": "^9.0.2","@fastify/static": "^8.0.4","@supabase/ssr": "^0.5.2","@supabase/supabase-js": "^2.47.16","dotenv": "^16.4.7","fastify": "^5.2.1",        ...    },"packageManager": "yarn@4.5.1"}

Code

Front:

Google sign-in button:

// AuthFormFooter.svelte<script>    // -- IMPORTS    ...    // -- FUNCTIONS    async function signInWithOAuth(        provider        )    {        ...        try        {            let redirectionToUrl;            switch ( platform )            {                case 'android':                    redirectionToUrl = 'com.myapp://auth';                    break;                case 'ios':                    redirectionToUrl = 'com.myapp://auth';                    break;                default:                    redirectionToUrl = 'http://localhost:5173/auth';            }            let data = await fetchData('/api/auth/open-auth',                {                    method: 'POST',                    headers: { 'Content-Type': 'application/json' },                    body: JSON.stringify( { provider, redirectionToUrl } )                }                );            if ( data.error )            {                console.error( 'Server sign-in error:', data.error );            }            else            {                if ( data.url )                {                    window.location.href = data.url;                }                else                {                    console.error( 'Server sign-in error:', data );                }            }        }        catch ( error )        {            console.error( errorText, error );        }    }</script><div class="auth-modal-socials"><div        class="auth-modal-socials-item"        on:click={() => signInWithOAuth( 'google' )}><span class="google-logo-icon size-150"></span></div></div>

Auth Callback:

// AuthPage.svelte<script>    // -- IMPORTS    import { onMount } from 'svelte';    import { fetchData } from '$lib/base';    import { navigate } from 'svelte-routing';    // -- FUNCTIONS    async function authCallback(        code,        next        )    {        try        {            let response = await fetchData('/api/auth/callback',                {                    method: 'POST',                    headers: { 'Content-Type': 'application/json' },                    body: JSON.stringify( { code } )                }                );            if ( response.success )            {                navigate( `/${ next.slice( 1 ) }`, { replace: true } );            }            else            {                console.error( 'Authentication failed' );            }        }        catch ( error )        {            console.error( 'Error during authentication', error );        }    }    onMount(        async () =>        {            let params = new URLSearchParams( window.location.search );            let code = params.get( 'code' );            let next = params.get( 'next' ) || '/';            if ( code )            {                await authCallback( code, next );            }            else            {                console.error( 'No code found in query params' );            }        }        );</script>

Server:

Supabase client configuration:

// supabase_service.jsclass SupabaseService{    // -- CONSTRUCTORS    constructor(        )    {        this.client = null;    }    // -- OPERATIONS    initalizeDatabaseClient(        request,        reply        )    {        this.client = createServerClient(            process.env.SUPABASE_DATABASE_URL,            process.env.SUPABASE_DATABASE_KEY,            {                cookies:                {                    getAll()                    {                        return parseCookieHeader( request.headers.cookie ?? '' );                    },                    setAll( cookiesToSet )                    {                        cookiesToSet.forEach(                            ( { name, value, options } ) =>                            {                                let serializedCookie = serializeCookieHeader( name, value, options );                                reply.header( 'Set-Cookie', serializedCookie );                            }                            );                    }                },                auth:                {                    flowType: 'pkce'                }            }            );    }    // ~~    getClient(        request,        reply        )    {        return this.client;    }}// -- VARIABLESexport let supabaseService    = new SupabaseService();

Auth controller:

// authentication_controller.js...// -- FUNCTIONS...// ~~async function openAuth(    request,    reply    ){    reply.header( 'Access-Control-Allow-Credentials', true );    reply.header( 'Access-Control-Allow-Origin', request.headers.origin );    let { redirectionToUrl, provider } = request.body;    try    {        let { data, error } = await supabaseService.getClient().auth.signInWithOAuth(            {                provider,                options: { redirectTo: redirectionToUrl }            }            );        if ( data.url )        {            let url = data.url;            return reply.code( 200 ).send( { url } );        }        else        {            return reply.code( 400 ).send( { error: 'auth-sign-in-failed' } );        }    }    catch ( error )    {        return reply.code( 500 ).send(            {                error: 'Server error', details: error            }            );    }}// ~~async function authCallback(    request,    reply    ){    reply.header( 'Access-Control-Allow-Credentials', true );    reply.header( 'Access-Control-Allow-Origin', request.headers.origin );    let code = request.body.code;    let route = request.body.route ?? '/';    try    {        if ( code )        {            let { data, error } =                await supabaseService.getClient().auth.exchangeCodeForSession( code );            if ( error )            {                return reply.code( 400 ).send(                    {                        success: false,                        error: error.message                    }                    );            }            return reply.code( 200 ).send(                {                    success: true,                    route                }                );        }        else        {            return reply.code( 400 ).send(                {                    success: false,                    error: 'No code provided'                }                );        }    }    catch ( error )    {        return reply.code( 500 ).send(            {                success: false,                error: 'Server error', details: error            }            );    }}// ~~...// -- EXPORTexport{    ...,    openAuth,    authCallback,    ...}

Updated all packages, enabled flow type pkce, implemented getAll and setAll instead of get, set and remove on cookies options. But all for nothing, got the same error and couldn't get the solution to this error


Viewing all articles
Browse latest Browse all 1541

Trending Articles