Victor Björklund

CORS error in Phoenix Elixir

Published: Jun 18 2023

You’ve just crafted an impressive API using Phoenix, and everything seems to be going smoothly… until the dreaded CORS-error starts haunting your dreams. It’s the bane of every web developer’s existence. Fear not, for you’re not alone in this struggle. As a developer who has battled this foe countless times, I’ve penned this post as reminder to myself on how to solve it.

What is a CORS-error?

Cross-Origin Resource Sharing (CORS) is a security mechanism enforced by web browsers to restrict cross-origin HTTP requests. It ensures that resources (such as APIs) are only accessed from the same origin, preventing unauthorized access to sensitive data. When developing a Phoenix app that communicates with external APIs or allows cross-origin requests, you may encounter CORS errors.

The solution

I assume that you have a frontend on one domain or port and a Phoenix backend on another domain or port and that is why you run into the issue. And your goal is for your frontend to be able to call your backend without any CORS-error. There are of course multiple ways to solve CORS issues (including avoiding it by running your API and frontend on the same domain and port by having a reverse proxy infront of it) but I will focus on the solution that uses “cors_plug”.

The first step is to install the “cors_plug” by adding {:cors_plug, "~> 3.0.3"} to your mix.exs and running mix deps.get.

In your router.ex file edit the pipeline for the api that you want to remove the CORS error from:

pipeline :api do
	plug :accepts, ["json"]
	plug CORSPlug, [origin: "https://example.com"]
end

Or if you want to allow requests from any domain (if you are for example building a public API)

pipeline :api do
	plug :accepts, ["json"]
	plug CORSPlug
end

However there is one “gotcha” here and it the fact that “cors_plug” will only run on matching routes so if your routes take in any path parameters and that resource doesn’t exist you will get a cors error instead of a more helpful error. For example if we have an API where we can request specific posts and a certain post is deleted and therefore that ID no longer exist.

To avoid this issue we need to explicitly add the options method to our routes like this:

scope "/posts", MyAppWeb do
	pipe_through :api
	post "/:post_id", PostController, :create
	options "/:post_id", PostController, :options
end

This ensures that cors_plug will run even if the post we request does not exist.

CORS errors can be frustrating, but with the proper configuration and understanding of how CORS works, you can overcome them in your Phoenix app. By following the steps outlined in this guide, you should be able to configure the necessary CORS settings in your Phoenix app and handle preflight requests effectively. Remember to fine-tune the CORS configuration based on your application’s requirements and security considerations.

CORS errors can be frustrating, but with the proper configuration and understanding of how CORS works, you can overcome them in your Phoenix app. By following the steps outlined in this guide, you should be able to configure the necessary CORS settings in your Phoenix app and handle preflight requests effectively. Remember to fine-tune the CORS configuration based on your application’s requirements and security considerations.

Frequently asked questions