oauth2

package
v0.0.0-...-abf8f43 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 22, 2024 License: Apache-2.0 Imports: 11 Imported by: 0

README

OAuth 2

The OAuth 2 handler allows to issue OAuth 2 sessions using JWTs and to check if requests are authenticated with them.

This allows you to use multiple IDPs at the same time and federate your sessions among them.

Usage

package main

import (
	"errors"
	"fmt"
	"log"
	"net/http"
	"net/url"
	"time"

	"github.com/cloudlena/adapters/oauth2"
	oa2 "golang.org/x/oauth2"
	"golang.org/x/oauth2/facebook"
)

// IndexHandler says what it loves.
func IndexHandler() http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
	})
}

// parseFacebookToken creates the private claims for an internal JWT from a Facebook OAuth2 token.
func parseFacebookToken(tok *oauth2.Token) (jwt.MapClaims, error) {
	meURL := "https://graph.facebook.com/me?fields=id,email,first_name,last_name&access_token=" + url.QueryEscape(tok.AccessToken)
	res, err := http.Get(meURL)
	if err != nil {
		return jwt.MapClaims{}, err
	}
	defer res.Body.Close()

	// Check if request was successful
	if res.StatusCode != http.StatusOK {
		return jwt.MapClaims{}, errors.New("invalid token")
	}

	return jwt.MapClaims{}, nil
}

func main() {
	sessionSecret := "my-session-secret" // Shouldn't be in your source code

	facebookConfig := &oa2.Config{
		ClientID:     "my-client-ID",
		ClientSecret: "my-client-secret",
		RedirectURL:  "http://localhost:8080/auth/callback/facebook",
		Endpoint:     facebook.Endpoint,
		Scopes:       []string{"email", "public_profile"},
	}
	http.Handle("/auth/login/facebook", oauth2.LoginHandler(facebookConfig))
	http.Handle("/auth/callback/facebook", oauth2.CallbackHandler(facebookConfig, sessionSecret, 24*time.Hour, parseFacebookToken))

	checkTokenMiddleware := oauth2.CheckTokenHandler(sessionSecret, "token")
	http.Handle("/", checkTokenMiddleware(IndexHandler()))
	log.Fatal(http.ListenAndServe(":8080", nil))
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CallbackHandler

func CallbackHandler(
	config *oa2.Config,
	sessionSecret string,
	tokenTTL time.Duration,
	parseTok ParseTokenFunc,
) http.Handler

CallbackHandler creates a session token and returns it to the client. It is designed to handle the OAuth2 callback endpoint.

func CheckTokenHandler

func CheckTokenHandler(
	sessionSecret string,
	tokenContextKey any,
) func(http.Handler) http.Handler

CheckTokenHandler checks if a request is authenticated through OAuth2. If it is, it will add the token to the request's context.

func LoginHandler

func LoginHandler(config *oa2.Config) http.Handler

LoginHandler triggers the respective login flow for the user.

func TokenLoginHandler

func TokenLoginHandler(
	sessionSecret string,
	tokenTTL time.Duration,
	parseTok ParseTokenFunc,
) http.Handler

TokenLoginHandler logs a user who already has an access token in.

Types

type ParseTokenFunc

type ParseTokenFunc func(*oa2.Token) (jwt.MapClaims, error)

ParseTokenFunc is a function to verify an external token and create private claims for the internal token from it.

type TokenResponse

type TokenResponse struct {
	TokenType   string `json:"tokenType"`
	AccessToken string `json:"accessToken"`
	ExpiresIn   int    `json:"expiresIn"`
}

TokenResponse is what the client will get upon successful login.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL