Table of Contents
- Introduction
- Prerequisites
- Setting Up a Go Web Application
- Understanding CORS
- Enabling CORS in a Go Server
- Handling CORS in Go Client
- Conclusion
Introduction
In this tutorial, we will explore how to handle Cross-Origin Resource Sharing (CORS) in a Go web application. Cross-origin requests are requests made from one domain to another domain, and by default, modern web browsers enforce strict security measures that prevent such requests. CORS allows a server to define who can access its resources, enabling controlled access from different domains.
By the end of this tutorial, you will have a solid understanding of how CORS works and how to handle it effectively in both the Go server and client sides.
Prerequisites
To follow along with this tutorial, you should have a basic understanding of Go programming language and web development concepts. You will need the following software installed on your machine:
- Go programming language (version 1.13 or later)
- A text editor or an integrated development environment (IDE) for writing Go code
Setting Up a Go Web Application
Before we dive into handling CORS, let’s set up a simple Go web application to work with. We will create a basic server that listens on a specific port and serves a static HTML page.
Start by creating a new directory for your project and navigate into it:
$ mkdir cors-webapp
$ cd cors-webapp
Next, initialize a new Go module:
$ go mod init github.com/your-username/cors-webapp
Create a new Go file named main.go
and open it in your text editor. Add the following code to set up a server and serve a static HTML page:
package main
import (
"log"
"net/http"
)
func main() {
// Define the handler for /
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "index.html")
})
// Start the server
log.Fatal(http.ListenAndServe(":8080", nil))
}
Create a new HTML file named index.html
in the same directory as main.go
:
<!DOCTYPE html>
<html>
<head>
<title>My CORS Web App</title>
</head>
<body>
<h1>Welcome to My CORS Web App!</h1>
</body>
</html>
Save the files, and you’re ready to move forward.
Understanding CORS
Before diving into the implementation details, it’s important to understand how CORS works. CORS involves both the server and the client side of a web application.
On the server side, the server sends additional HTTP headers to the client to define the CORS policy. These headers include Access-Control-Allow-Origin
, Access-Control-Allow-Methods
, Access-Control-Allow-Headers
, and Access-Control-Allow-Credentials
, among others.
On the client side, a web browser checks the response headers of an outgoing request to determine if it’s a cross-origin request. If it is, the browser then checks the received headers from the server to validate whether it has permission to access the requested resource.
Enabling CORS in a Go Server
To enable CORS in a Go server, we need to set the appropriate response headers for each incoming request. These headers communicate the server’s CORS policy to the client.
Modify the main
function in main.go
as follows:
package main
import (
"log"
"net/http"
)
func main() {
// Define the handler for /
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
// Set CORS headers
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
w.Header().Set("Access-Control-Allow-Credentials", "true")
// Serve the static HTML page
http.ServeFile(w, r, "index.html")
})
// Start the server
log.Fatal(http.ListenAndServe(":8080", nil))
}
In the modified code, we added the necessary w.Header()
calls to set the CORS headers for each request. The Access-Control-Allow-Origin
header is set to *
, allowing all origins to access the resources. You can change this value to a specific domain if needed.
The Access-Control-Allow-Methods
header defines the HTTP methods allowed for cross-origin requests, such as GET, POST, PUT, and DELETE. Modify this header according to your application’s needs.
The Access-Control-Allow-Headers
header specifies the request headers allowed for cross-origin requests. In this example, we only allow the Content-Type
header, but you can add more headers as necessary.
The Access-Control-Allow-Credentials
header allows credentials (like cookies or HTTP authentication) to be sent in cross-origin requests. Setting it to true
enables cookies to be passed to the server.
With these changes, our Go web server now supports CORS.
Handling CORS in Go Client
Now let’s see how to handle CORS in a Go client by making a cross-origin request to the server we just set up.
Create a new file named client.go
in the same directory as main.go
and add the following code:
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
)
func main() {
// Make a GET request to the server we set up
res, err := http.Get("http://localhost:8080")
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
// Read the response body
body, err := ioutil.ReadAll(res.Body)
if err != nil {
log.Fatal(err)
}
// Print the response body
fmt.Println(string(body))
}
In the main
function of client.go
, we make a GET request to the server at http://localhost:8080
. Since this is a cross-origin request, the browser will enforce CORS restrictions. However, Go’s http
package already handles the necessary CORS headers internally.
After receiving the response, we read the response body and print it to the console.
To run the client, open a terminal and navigate to the project directory. Then, execute the following command:
$ go run client.go
You should see the response body printed, which contains the HTML content of the static page served by the server.
Conclusion
In this tutorial, you learned how to handle Cross-Origin Resource Sharing (CORS) in a Go web application. We explored the concepts of CORS, set up a simple Go web server, and enabled CORS in both the server and client sides.
By setting the appropriate response headers, we allowed cross-origin requests to access the server’s resources. We also made a cross-origin request from the Go client and successfully received the response.
Now that you have a good understanding of CORS and how to handle it in Go, you can apply this knowledge to your own web applications to enable controlled access from different domains.
Remember to always consider the security implications of enabling CORS and define your CORS policy based on your application’s requirements and domain trust.
Happy coding!