Restricting API Access in Saleor Environments
Even though Saleor implements complex authorization and authentication mechanisms, you might want to restrict access to your Saleor Environment 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.
Trusted client origins
Trusted client origins are the allowed domains used in sensitive user flows such as account registration, password reset, and email confirmations.
- Values must be full URLs, including the scheme, domain, and optional port.
Example:
https://mystorefront.example.com
Allowed API origins (CORS)
This controls the Cross-Origin Resource Sharing (CORS) settings. 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 environment view, 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”.
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.
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:
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:
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 (
// ...
);
}
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);
};
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",
},
// ...
});
// ...
}