Skip to main content

Restricting API Access

Even though Saleor implements complex authorization and authentication mechanisms, you might want to restrict access to your Saleor Cloud instance for specific use cases.

Below, we explore two ways Saleor Cloud allows you to restrict access to the API, as well as a practical example of how to use one of them.

Allowed API origins

If the list of the origins you expect to call your API is known in advance, you can automatically reject the unknown ones.

In the project view of your Saleor Cloud dashboard, you can customize the allowed origins. The default option is to "Allow All" but you can also specify a list of origins or set it to "Dashboard only".

warning

We don't recommend using the "Allow All" setting on production environments. It's a good practice to restrict the access to the API to only the origins you expect.

info

Changing the settings to only allow the selected origins can affect the installed apps. If you want your app to call the Saleor API from the client, you need to add the app's origin to the list of allowed origins. You can read more about the app's access scopes in the App permissions document.

You don't need to specify the Saleor Cloud dashboard origin, as it is always allowed to call the Saleor API.

API Password Protection

Another way to restrict access to your Saleor Cloud instance is to protect it with a password through Basic Auth. This way, you can ensure that only those with the credentials can access the API.

important

After enabling password protection, users trying to open the Saleor Dashboard will be prompted to enter the Basic Auth username and password besides their own Saleor Cloud credentials.

Combined with a server-side proxy, this can be a useful tool to obscure the Saleor API from unauthorized access. We will explore this in more detail in the example below.

Example: Password-protected API proxy

Overview

By default, Saleor exposes some parts of its API publicly, like product catalog or checkout. This behavior doesn't have to align with the requirements of your business. However, Saleor Cloud allows you to restrict access to the API by setting up a Basic Auth.

Imagine you don't want your products to be publicly accessible. To achieve this, we will create a proxy server that will know the credentials and the API URL and thus be able to access the Saleor API. The only way to get to the Saleor API will be through that proxy server.

Here is how it may look in practice in the example of a simple Next.js application. At the moment, it calls the Saleor API directly:

info

Next.js gives you the ability to create API routes, which are server-side endpoints that must be created in the pages/api directory.

While we chose to use Next.js in this example, you can use any server-side technology to create the proxy server.

Implementation

Step 1: Protect the Saleor API with a password

Set up "API Password Protection" in the Saleor Cloud dashboard as described above.

Step 2: Visit your current implementation

In the current implementation, your Next.js application calls the Saleor API directly:

note

In a production-grade Next.js application, you most likely would use some GraphQL client (like Apollo Client) to fetch the data from the Saleor API. However, for simplicity, we will use the native fetch API in this example.

async function getProducts() {
const response = await fetch("https://your-store.saleor.cloud/graphql", { // The URL of your Saleor instance
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
// The GraphQL query you want to execute
query: `
query GetProducts {
products(first: 10) {
edges {
node {
id
}
}
}
}
`,
}),
});

const data = await response.json();

// ...
}

const ProductList = () => {
useEffect(() => {
getProducts();
}, []);

return (
// ...
);
}
Expand ▼

Our goal is to change the code above as little as possible when introducing the proxy server.

Step 3: Create a proxy API route

In most cases, you would call the Saleor GraphQL API straight from the React component. However, given that we want to obscure the Saleor API behind Basic Auth, we can't just pass the credentials to the client. They would be easily accessible to anyone who inspects the code.

Instead, we will create a proxy API route that will know our GraphQL endpoint's credentials and address. As long as we don't expose the credentials to the client, we are sure that our proxy server is the only one that can access the Saleor API directly.

Here is what the proxy API route may look like:

// pages/api/saleor.js
export default async (req, res) => {
const username = process.env.SALEOR_API_USERNAME; // Take the Basic Auth username from an environment variable
const password = process.env.SALEOR_API_PASSWORD; // Take the Basic Auth password from an environment variable
const token = Buffer.from(`${username}:${password}`).toString("base64"); // Encode the credentials to Base64

const response = await fetch("https://your-store.saleor.cloud/graphql", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Basic ${token}`, // Using the Basic Auth header to authenticate the Saleor API
},
body: JSON.stringify({
query: `
// Read the query from the request body
`,
}),
});

res.status(200).json(data);
};
Expand ▼

Step 4: Update the Next.js application to use the proxy

Our last step will be to update the client-side code to fetch products via the route we just implemented:

async function getProducts() {
// Using the proxy API route instead of the Saleor API directly
const response = await fetch("/api/saleor", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
// ...
});
// ...
}