programming

13 Building OAuth 2.0 Authentication Middleware with httprouter in Go

In modern programming, application security is a top priority, especially when dealing with user authentication. One widely used authentication method today is OAuth 2.0, which allows applications to access user resources without exposing their credentials. In this article, we will discuss how to create an authentication middleware using OAuth 2.0 with Go and the httprouter library.

What is OAuth 2.0?

OAuth 2.0 is an authentication and authorization protocol that enables third-party applications to obtain limited access to user resources without sharing user credentials. This protocol is widely used by major services such as Google, Facebook, and GitHub to allow users to log in with their existing accounts.

In this implementation, users will be prompted to log in via an authentication provider (such as Google or GitHub), and our application will obtain an access token that grants access to the user’s data.

Why Use httprouter?

The httprouter library is a fast and lightweight HTTP router for Go applications. It is highly suitable for Go applications due to its high performance and simplicity. Using httprouter, we can efficiently handle HTTP requests.

In this tutorial, we will utilize httprouter to create OAuth 2.0 authentication middleware.

Prerequisites

Before we begin, ensure you have the following:

  1. Go: Make sure Go is installed on your system.
  2. httprouter Library: We will use this library to manage HTTP routes.
  3. OAuth 2.0 Credentials: You need to register an application with an OAuth provider (such as Google or GitHub) to obtain client credentials (client ID and client secret).

Install httprouter by running:

go get github.com/julienschmidt/httprouter

1. Setting Up the OAuth 2.0 Environment

The first step is to create an application with your chosen OAuth 2.0 provider (e.g., Google). You will need to obtain a client ID and client secret from the provider.

If you choose Google, you can do this by visiting the Google Developers Console and creating a new project. Then, generate OAuth 2.0 credentials and save the client ID and client secret.

2. Using OAuth 2.0 Library for Go

Go provides several libraries for working with OAuth 2.0, with golang.org/x/oauth2 being one of the most popular.

To install it, run:

go get golang.org/x/oauth2
go get golang.org/x/oauth2/google

3. Creating the Authentication Middleware

Now, we will create middleware that checks for an OAuth 2.0 access token in every HTTP request. If the token is valid, the request proceeds; otherwise, users are redirected to the login page.

Here’s how to implement the authentication middleware using OAuth 2.0:

package main

import (
    "fmt"
    "log"
    "net/http"

    "github.com/julienschmidt/httprouter"
    "golang.org/x/oauth2"
    "golang.org/x/oauth2/google"
)

var oauth2Config oauth2.Config

// OAuth2 middleware to check for valid token
func oauth2Middleware(next httprouter.Handle) httprouter.Handle {
    return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
        token, err := oauth2Config.TokenSource(r.Context()).Token()
        if err != nil || !token.Valid() {
            http.Redirect(w, r, oauth2Config.AuthCodeURL("", oauth2.AccessTypeOffline), http.StatusFound)
            return
        }
        next(w, r, ps)
    }
}

// HomeHandler protected by OAuth2 middleware
func homeHandler(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
    fmt.Fprintf(w, "Welcome, you are authenticated!")
}

func main() {
    oauth2Config = oauth2.Config{
        ClientID:     "YOUR_CLIENT_ID",
        ClientSecret: "YOUR_CLIENT_SECRET",
        RedirectURL:  "http://localhost:8080/callback",
        Scopes:       []string{"openid", "profile", "email"},
        Endpoint:     google.Endpoint,
    }

    router := httprouter.New()

    // Protect /home route with OAuth2 middleware
    router.GET("/home", oauth2Middleware(homeHandler))

    log.Println("Starting server on :8080")
    log.Fatal(http.ListenAndServe(":8080", router))
}

4. Adding the Callback Route

Once a user successfully logs in, the OAuth 2.0 provider will redirect them to your application’s specified callback URL. Here’s how to handle the callback:

func callbackHandler(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
    code := r.URL.Query().Get("code")
    token, err := oauth2Config.Exchange(r.Context(), code)
    if err != nil {
        http.Error(w, "Failed to get token: "+err.Error(), http.StatusInternalServerError)
        return
    }

    // Save token for future requests
    fmt.Fprintf(w, "You are authenticated! Token: %s", token.AccessToken)
}

Add the route for callback handling:

router.GET("/callback", callbackHandler)

5. Writing Unit Tests

To ensure the authentication middleware functions correctly, we can write unit tests for oauth2Middleware and callbackHandler.

Run the tests using:

go test -v

Conclusion

Creating authentication middleware using OAuth 2.0 with Go and httprouter is an effective way to secure your application and provide authenticated access to users. By following this tutorial, you have learned how to set up OAuth 2.0, implement middleware, and protect routes in your Go application.

For more Go-related tutorials, visit Golang Tutorials.

If you’re interested in learning more about HTTP routing in Go, check out Web HTTP Router in Golang.

comments powered by Disqus