Authentication issues with API.

AI-generated summary

Main issue: In a Remix-based Shopify app, authenticate.admin(request) fails in a loader because the request lacks an access token, while standard routes correctly include the user session. The author asks how to authenticate API routes in this setup.

Proposed approach:

  • Ensure session middleware is properly configured to store and retrieve the user’s access token.
  • In loaders or API handlers, manually read the session from the Cookie header, extract accessToken, and enforce auth:
    • If no token, return 401 Unauthorized.
    • Use authenticate.admin({ token: accessToken }); if it fails, return 403.
  • Then proceed with the route/API logic.

Technical notes: Remix “loader” runs server-side to fetch data before rendering. Access tokens should be retrieved from the server-side session rather than relying on the incoming request object. The provided code snippets (loader and API handler) are central to implementing this.

Status/outcome: A clear server-side pattern is proposed, but there’s no confirmation from the original poster that it resolves the issue; discussion appears open.

I’m trying to create a route via a Shopify app using Remix, but I’m facing an authentication issue. When I create a route with load, the authenticate.admin(request) doesn’t work because the request doesn’t include the access token. In a regular route, it brings the user’s session. Is there a way to authenticate with Shopify when creating an API route in Remix app? How can I achieve this?

Hi @wandersoncorrea

To address the authentication issue in a Remix app, follow these steps:

  1. Ensure Session Middleware: Verify your session middleware is set up to handle the user’s session and access token.

  2. Manually Include Access Token: Add the access token to your request manually if it’s not included automatically. Example:

import { authenticate } from 'shopify-auth';
import { getSession } from './session';

export const loader = async ({ request }) => {
  const session = await getSession(request.headers.get('Cookie'));
  const accessToken = session.get('accessToken');

  if (!accessToken) {
    throw new Response('Unauthorized', { status: 401 });
  }

  const authResponse = await authenticate.admin({ token: accessToken });

  if (!authResponse) {
    throw new Response('Authentication failed', { status: 403 });
  }

  return { authResponse };
};
  • API Route Authentication: For API routes, ensure the access token is included in your server-side logic:
import { authenticate } from 'shopify-auth';
import { getSession } from './session';

export async function apiHandler(request) {
  const session = await getSession(request.headers.get('Cookie'));
  const accessToken = session.get('accessToken');

  if (!accessToken) {
    return new Response('Unauthorized', { status: 401 });
  }

  const authResponse = await authenticate.admin({ token: accessToken });

  if (!authResponse) {
    return new Response('Authentication failed', { status: 403 });
  }

  // Proceed with your API logic here
}
​

These steps should help resolve your authentication issue.