5.2.6. Protected Routes

In this chapter, you’ll learn how to create protected routes.

What is a Protected Route?#

A protected route is a route that requires requests to be user-authenticated before performing the route's functionality. Otherwise, the request fails, and the user is prevented access.


Default Protected Routes#

Medusa applies an authentication guard on routes starting with /admin, including custom API routes.

Requests to /admin must be user-authenticated to access the route.

TipRefer to the API Reference for Admin and Store authentication methods.

Protect Custom API Routes#

To protect custom API Routes to only allow authenticated customer or admin users, use the authenticate middleware imported from @medusajs/medusa.

For example:

src/api/middlewares.ts
1import { 2  defineMiddlewares,3  authenticate,4} from "@medusajs/medusa"5
6export default defineMiddlewares({7  routes: [8    {9      matcher: "/custom/admin*",10      middlewares: [authenticate("user", ["session", "bearer", "api-key"])],11    },12    {13      matcher: "/custom/customer*",14      middlewares: [authenticate("customer", ["session", "bearer"])],15    },16  ],17})

The authenticate middleware function accepts three parameters:

  1. The type of user authenticating. Use user for authenticating admin users, and customer for authenticating customers. You can also pass * to allow all types of users.
  2. An array of types of authentication methods allowed. Both user and customer scopes support session and bearer. The admin scope also supports the api-key authentication method.
  3. An optional object of configurations accepting the following property:
    • allowUnauthenticated: (default: false) A boolean indicating whether authentication is required. For example, you may have an API route where you want to access the logged-in customer if available, but guest customers can still access it too.

Authentication Opt-Out#

To disable the authentication guard on custom routes under the /admin path prefix, export an AUTHENTICATE variable in the route file with its value set to false.

For example:

src/api/admin/custom/route.ts
1import type { 2  AuthenticatedMedusaRequest, 3  MedusaResponse,4} from "@medusajs/framework/http"5
6export const GET = async (7  req: AuthenticatedMedusaRequest, 8  res: MedusaResponse9) => {10  res.json({11    message: "Hello",12  })13}14
15export const AUTHENTICATE = false

Now, any request sent to the /admin/custom API route is allowed, regardless if the admin user is authenticated.


Authenticated Request Type#

To access the authentication details in an API route, such as the logged-in user's ID, set the type of the first request parameter to AuthenticatedMedusaRequest. It extends MedusaRequest.

The auth_context.actor_id property of AuthenticatedMedusaRequest holds the ID of the authenticated user or customer. If there isn't any authenticated user or customer, auth_context is undefined.

NoteIf you opt-out of authentication in a route as mentioned in the previous section , you can't access the authenticated user or customer anymore. Use the authenticate middleware instead.

Retrieve Logged-In Customer's Details#

You can access the logged-in customer’s ID in all API routes starting with /store using the auth_context.actor_id property of the AuthenticatedMedusaRequest object.

For example:

src/api/store/custom/route.ts
6import { ICustomerModuleService } from "@medusajs/framework/types"7
8export const GET = async (9  req: AuthenticatedMedusaRequest,10  res: MedusaResponse11) => {12  if (req.auth_context?.actor_id) {13    // retrieve customer14    const customerModuleService: ICustomerModuleService = req.scope.resolve(15      Modules.CUSTOMER16    )17
18    const customer = await customerModuleService.retrieveCustomer(19      req.auth_context.actor_id20    )21  }22
23  // ...24}

In this example, you resolve the Customer Module's main service, then use it to retrieve the logged-in customer, if available.

Retrieve Logged-In Admin User's Details#

You can access the logged-in admin user’s ID in all API Routes starting with /admin using the auth_context.actor_id property of the AuthenticatedMedusaRequest object.

For example:

src/api/admin/custom/route.ts
6import { IUserModuleService } from "@medusajs/framework/types"7
8export const GET = async (9  req: AuthenticatedMedusaRequest,10  res: MedusaResponse11) => {12  const userModuleService: IUserModuleService = req.scope.resolve(13    Modules.USER14  )15
16  const user = await userModuleService.retrieveUser(17    req.auth_context.actor_id18  )19
20  // ...21}

In the route handler, you resolve the User Module's main service, then use it to retrieve the logged-in admin user.

Was this chapter helpful?
Edit this page