Handling CORS in API Routes

In this chapter, you'll learn about the CORS middleware and how to configure it for custom API routes.

CORS Overview#

Cross-Origin Resource Sharing (CORS) allows only configured origins to access your API routes.

For example, if you allow only origins starting with http://localhost:7001 to access your Admin API routes, other origins accessing those routes get a CORS error.

CORS Configurations#

The StoreCors, AdminCors, and AuthCors properties of the HTTP configuration set the allowed origins for routes starting with /store, /admin, and /auth respectively.

These configurations accept a comma-separated list of origins. An origin can also be a regular expression, between slashes, such as /^https:\/\/.*\.example\.com$/.

For example:

medusa-config.go
// medusaConfig is the project configuration (medusa-config.go). The CORS
// settings accept a comma-separated list of origins, or a regular expression
// between slashes.
func medusaConfig() config.InputConfig {
	return config.InputConfig{
		ProjectConfig: config.ProjectConfig{
			HTTP: config.HttpConfig{
				StoreCors: "http://localhost:8000",
				AdminCors: "http://localhost:7001",
			},
		},
	}
}

This allows the http://localhost:7001 origin to access the Admin API routes, and the http://localhost:8000 origin to access Store API routes.

If you don't set a property, its value is the STORE_CORS, ADMIN_CORS, or AUTH_CORS environment variable, or a default value for local development.

Tip: Learn more about the CORS configurations in this reference.

CORS in Store and Admin Routes#

To disable the CORS middleware for a route, set the Cors property of the route's Route to false. It's a *bool, and nil means the middleware is applied.

For example:

src/api/store/custom-hello/route.go
func storeCustomGET(req *medusahttp.MedusaRequest, res *medusahttp.MedusaResponse) error {
	return res.JSON(map[string]any{"message": "[GET] Hello world!"})
}

// StoreCustomNoCorsRoute disables the CORS middleware for /store/custom-hello.
var StoreCustomNoCorsRoute = medusahttp.RouteFile{
	Path: "/store/custom-hello",
	Route: medusahttp.Route{
		GET:  storeCustomGET,
		Cors: ptr(false),
	},
}

This disables the CORS middleware on API routes at the path /store/custom-hello. The ptr function in this example returns a pointer to the value you pass.


CORS in Custom Routes#

If you create a route that doesn't start with /store, /admin, or /auth, you must apply the CORS middleware manually. Otherwise, all requests to your API route from other origins lead to a CORS error.

You can do that with a middleware in the middleware configurations of your project.

For example:

src/api/middlewares.go
// corsForCustomRoutes applies the storeCors configuration to the routes it
// is registered for.
func corsForCustomRoutes(req *medusahttp.MedusaRequest, res *medusahttp.MedusaResponse, next medusahttp.NextFunction) error {
	cfg, _ := req.Scope.Resolve(common.ContainerRegistrationKeys.CONFIG_MODULE).(config.ConfigModule)

	origins := medusahttp.ParseCorsOrigins(cfg.ProjectConfig.HTTP.StoreCors)
	return medusahttp.Cors(origins)(req, res, next)
}

// CorsMiddleware applies CORS to every route starting with /custom.
var CorsMiddleware = medusahttp.MiddlewareRoute{
	Matcher:     "/custom*",
	Middlewares: []medusahttp.MiddlewareFunction{corsForCustomRoutes},
}

This retrieves the configurations of your application from the container, and applies the StoreCors configuration to routes starting with /custom. The Cors function from the framework/src/http package returns the CORS middleware, and ParseCorsOrigins parses a configuration value into the allowed origins.

The CORS middleware answers OPTIONS preflight requests itself, with a 204 status code, so you don't need to add a handler for them.

Found a problem with this page?Report Issue
Edited Nov 14·Edit this page