ylliX - Online Advertising Network
Vertex AI - Antrophic and Mistral models: Why does it require Imegen access?

How do I log out of the Shopify API at the same time as my Astro app?


I am trying to implement user auth using the Shopify Headless customer account API in an Astro app with auth-astro. I have set up my Shopify store with the Headless app properly, I can log in, maintain a session and it all works nicely. What I can’t work out how to do is log out properly. Even if I use the built-in Log out method of AuthJS, the Shopify account remains logged in.

The correct method to log out of Shopify is a GET request to their endpoint with the ID token as a URL parameter as documented here: https://shopify.dev/docs/api/customer#step-logging-out

The AuthJS docs don’t have much on how to edit the logout functions. It simply clears your local session data and redirects you to a local URL. https://authjs.dev/getting-started/session-management/login

My auth.config.mjs file looks like the following and this is where I guess I need to make the change.

import { defineConfig } from 'auth-astro';
const CUSTOMER_ACCOUNT = `#graphql
query {
    customer {
        id
        emailAddress { 
            emailAddress 
        }
        firstName
        lastName
    }
}`;

export default defineConfig({
    providers: [
        {
            id: 'shopify',
            name: 'Shopify',
            type: 'oauth',
            clientId: import.meta.env.PUBLIC_SHOPIFY_CUSTOMER_ACCESS_TOKEN,
            clientSecret: import.meta.env.PRIVATE_SHOPIFY_CUSTOMER_ACCESS_TOKEN,
            issuer: `https://shopify.com/authentication/${import.meta.env.PUBLIC_SHOPIFY_STORE_ID}`,
            authorization: {
                url: `https://shopify.com/${import.meta.env.PUBLIC_SHOPIFY_STORE_ID}/auth/oauth/authorize`,
                params: {
                    scope: 'openid email https://api.customers.com/auth/customer.graphql',
                    client_id: import.meta.env.PUBLIC_SHOPIFY_CUSTOMER_ACCESS_TOKEN,
                    response_type: 'code',
                    redirect_uri: `${import.meta.env.SITE_URL}/api/auth/callback/shopify`,
                },
            },
            token: {
                url: `https://shopify.com/authentication/${import.meta.env.PUBLIC_SHOPIFY_STORE_ID}/oauth/token`,
                params: {
                    client_id: import.meta.env.PUBLIC_SHOPIFY_CUSTOMER_ACCESS_TOKEN,
                    client_secret: import.meta.env.PRIVATE_SHOPIFY_CUSTOMER_ACCESS_TOKEN,
                    grant_type: 'authorization_code',
                    redirect_uri: `${import.meta.env.SITE_URL}/api/auth/callback/shopify`,
                },
            },
            userinfo: {
                url: `https://shopify.com/${import.meta.env.PUBLIC_SHOPIFY_STORE_ID}/account/customer/api/${import.meta.env.SHOPIFY_APP_VERSION}/graphql`,
                async request(context) {
                    const response = await fetch(this.url, {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                            Authorization: `${context.tokens.access_token}`,
                        },
                        body: JSON.stringify({
                            operationName: 'GetCustomer',
                            query: CUSTOMER_ACCOUNT,
                            variables: {},
                        }),
                    });
                    const { data } = await response.json();
                    const { customer } = data;
                    customer.id_token = context.tokens.id_token;
                    return customer;
                }
            },
            profile(data) {
                return {
                    id: data.id,
                    firstName: data.firstName,
                    lastName: data.lastName,
                    email: data.emailAddress.emailAddress,
                    id_token: data.id_token,
                };
            }
        },
    ],
    callbacks: {
        async session({ session, token }) {
            if (token) {
                session.user = token.user;
            }
            return session;
        },
        async jwt({ token, user, profile }) {
            if (user) {
                token.user = user;
            }
            if (profile && profile.id) {
                token.graphId = profile.id;
            }
            return token;
        },
    },
});

I considered using events, but they’re asynchronous and therefore a get request to the Shopify logout URL wouldn’t be appropriate as the users browser has to navigate to the URL.

I tried redirecting back from Shopify to the logout route of AuthJS but because it’s a GET and not a POST request it renders a logout confirmation page.

My best guess is to use the redirect callback in AuthJS somehow https://authjs.dev/reference/core/types#redirect perhaps by inspecting the local URL and redirecting to Shopify as the users session ends. I am not sure how I could retrieve the users id_token from the session in that instance.

Any suggestions would be greatly appreciated.



Source link

Leave a Reply

Your email address will not be published. Required fields are marked *