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:
// 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.
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:
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:
// 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.