In web application development, cross-origin issues have become a popular topic. However, with the widespread adoption of API gateways, we now have a more convenient and efficient solution to address cross-origin problems. The API gateway, as a key component in the application architecture, not only provides functionalities such as request routing and API management but also effectively handles cross-origin requests, helping developers bypass the browser's same-origin policy restrictions. This article will delve into how to use the API gateway APISIX to solve cross-origin problems.
What Is Cross-Origin?
Cross-origin issues primarily arise from the same-origin policy enforced by browsers. The same-origin policy requires that the source (protocol, domain, port) of a request must be exactly identical to the target resource; otherwise, the browser will block the request. This policy aims to protect user information security and prevent malicious websites from stealing data. However, in practical development, scenarios like frontend-backend separation or deployment with different domains or ports often lead to cross-origin problems.
Solving Cross-Origin Issues Using APISIX
CORS (Cross-Origin Resource Sharing)
CORS (Cross-Origin Resource Sharing) is a W3C standard that enables browsers to send requests to cross-origin servers, overcoming the restrictions imposed by the same-origin policy. In APISIX, developers can effortlessly configure CORS rules using the CORS plugin, specifying which sources are allowed to access resources.
Example command using curl to configure CORS in APISIX:
curl http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' { "uri": "/hello", "plugins": { "cors": {} }, "upstream": { "type": "roundrobin", "nodes": { "127.0.0.1:8080": 1 } } }'
This command uses curl
to send a PUT request to the Admin API of APISIX, creating a route with the ID of 1. The route is configured with a URI path of /hello
, and the default configuration enables the CORS plugin. Additionally, the upstream server is specified as 127.0.0.1:8080
.
Executing a test request will get the default configuration results:
curl http://127.0.0.1:9080/hello -v
...
< Server: APISIX web server
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: *
< Access-Control-Allow-Headers: *
< Access-Control-Expose-Headers: *
< Access-Control-Max-Age: 5
...
If adjustments to the CORS policy are necessary, simply modify the relevant plugin configurations. Here are several commonly used configuration options:
allow_origins
: Specifies the origins allowed for cross-origin access. It can be a specific URL or use the wildcard '*' to allow all origins. Multiple values are separated by commas.allow_methods
: Defines the HTTP methods allowed for cross-origin access, such as GET, POST, etc. Multiple values are separated by commas.allow_headers
: Permits custom header fields to be carried in cross-origin requests. Multiple values are separated by commas.expose_headers
: Specifies custom header fields to be exposed in cross-origin responses. Multiple values are separated by commas.max_age
: Sets the maximum time for the browser to cache CORS responses.allow_credentials
: Determines whether to allow carrying credentials (such as Cookies) in cross-origin requests.
Points to Note
Special attention should be given to the fact that although CORS is easy to use, enabling it may lead to security issues. This is primarily because CORS relaxes the restrictions imposed by the same-origin policy, allowing requests from different origins to access resources.
In this context, let's focus on allow_credentials
. allow_credentials
is a crucial configuration item in CORS, determining whether cross-origin requests are allowed to carry authentication information. This includes, but is not limited to sensitive data, including cookies, HTTP authentication information, or client SSL certificates.
By default, allow_credentials
is disabled, meaning it does not allow the carrying of authentication information. However, if CORS is enabled, and it allows carrying authentication information (allow_credentials: true
), extra caution is necessary. This implies that requests from other origins can also access protected resources, potentially executing sensitive operations. For example, a malicious website exploiting this configuration vulnerability might induce users to initiate cross-origin requests, leading to the theft of their session cookies or unauthorized actions.
To minimize potential security issues when enabling cross-origin requests, it is advisable to adhere to the following best practices:
-
Carefully configure
allow_origin
: Avoid settingallow_origin
to*
(allow all sources) indiscriminately. Instead, explicitly specify the allowed sources. -
Limit
allow_credentials
: Enableallow_credentials
only when necessary and restrict it to trusted sources. - Use a secure transport protocol: Ensure that CORS requests are transmitted over HTTPS to prevent man-in-the-middle attacks.
- Validation and authorization: On the backend server, implement proper validation and authorization checks for cross-origin requests, ensuring that only authorized users can access sensitive resources.
- Avoid using insecure HTTP methods: Restrict the HTTP methods used in cross-origin requests, allowing only safe methods such as GET and POST, while disabling potentially risky methods like PUT and DELETE, which may pose security risks.
Reverse Proxy
In addition to using CORS, APISIX can indirectly address cross-origin issues by configuring itself as a reverse proxy. A reverse proxy is a common server architecture pattern where the reverse proxy server acts as an intermediary between the client and the target server. When a client initiates a request, these requests are first sent to the reverse proxy server, which then forwards them to the actual target server. Once processing is complete, the response from the target server is returned to the reverse proxy, ultimately passed back to the client.
It is crucial to understand that a reverse proxy itself does not directly solve cross-origin problems but cleverly bypasses the browser's same-origin policy restrictions. When a client needs to make a cross-origin request, it actually sends the request to the reverse proxy server instead of directly to the target server. Since the reverse proxy server and the target server are typically in the same network environment or configuration, their communication is not subject to the same-origin policy restrictions. This allows the reverse proxy server to freely forward the client's requests to the target server and return the responses to the client, indirectly achieving the goal of cross-origin access.
As APISIX serves as an API gateway, it is inherently positioned to be deployed between the client and server. Therefore, in smaller-scale applications, deploying the client application and APISIX in the same domain and modifying the client's request address to the APISIX service address ensures smooth client access to APISIX. This can leverage the reverse proxy functionality to provide cross-origin access for the client. Additionally, other plugins can be combined to ensure the security and reliability of the entire communication process.
Conclusion
In this article, we have explored how to use APISIX to address cross-origin issues, with a focus on two methods: CORS and reverse proxy. By configuring the CORS plugin appropriately, we can relax the same-origin policy restrictions imposed by browsers, allowing cross-origin requests to access resources. On the other hand, reverse proxy acts as an intermediary, circumventing the same-origin policy of browsers and facilitating cross-origin access. Each method has its advantages, and the choice of the appropriate solution depends on specific requirements. Whether employing CORS or reverse proxy, APISIX offers flexible and powerful functionalities, aiding developers in seamlessly resolving cross-origin issues and ensuring the normal operation and user experience of applications.