tideauth

package module
v1.4.0 Latest Latest
Warning

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

Go to latest
Published: Sep 2, 2026 License: MIT Imports: 13 Imported by: 0

README

tideauth

The threetides studio's authentication package.

tideauth is a Go package that handles every aspect of authentication for the studio's services: OAuth2 and OIDC sign-in, sessions, and the user data tables behind them. A service imports the package, fills in a Config, and gets back its migrations, a set of net/http routes to mount, and middleware for protecting its own routes, with no auth code of its own. It currently supports email and password sign-in and Google sign-in, with more providers to come.

Usage

Install the package:

go get github.com/threetides/tideauth@latest

Configure it, run its migrations, and mount its routes:

// Connect to db
db, err := pgxpool.New(context.Background(), os.Getenv("DB_CONNECTION_STRING"))
if err != nil {
	log.Fatalln("Error connecting to db:", err)
}

// Create config for tideauth
cfg := tideauth.Config{
	DB:           db,
	CookieDomain: "example.com",
	Google: tideauth.Google{
		ClientID:     os.Getenv("GOOGLE_CLIENT_ID"),
		ClientSecret: os.Getenv("GOOGLE_CLIENT_SECRET"),
		RedirectURL:  os.Getenv("REDIRECT_URL") + "/api/auth/google/callback",
	},
}

auth := tideauth.New(cfg)

// Run migrations
err = auth.Migrate(context.Background())
if err != nil {
	log.Fatalln("Error running migrations:", err)
}

// Create default routes exported by tideauth
routes, err := auth.Routes()
if err != nil {
	log.Fatalln("Error setting up routes:", err)
}

// Handlers
mux.Handle("/api/auth/", http.StripPrefix("/api/auth", routes))

// Protect your own routes with the session middleware
mux.HandleFunc("GET /api/me", auth.Protected(meHandler))

API

New
func New(cfg Config) *Auth

Creates an Auth from the config. It does no I/O; the pgx pool is created, owned, and closed by the caller.

Migrate
func (a *Auth) Migrate(ctx context.Context) error

Applies the embedded SQL migrations, creating and maintaining the user data tables: users, oauth_accounts, passwords, and sessions. Safe to run on every startup.

Routes
func (a *Auth) Routes() (http.Handler, error)

Returns a handler serving the auth endpoints:

POST /sign-up            create a user with email and password
                         body: { "email", "name", "password" }

POST /sign-in            sign in with email and password
                         body: { "email", "password" }

GET  /google/sign-in     redirect to Google's consent screen

GET  /google/callback    complete the Google sign-in

GET  /session            the signed-in user's profile

POST /sign-out           end the session

Bodies are JSON and every field is a string. Sign-up validates the email address and stores the password as a bcrypt hash.

Protected
func (a *Auth) Protected(next http.HandlerFunc) http.HandlerFunc

Wraps a handler with session validation: it checks the session cookie against the database, slides the session's expiry another 30 days, and puts the user's id in the request context. Requests without a valid session get a 401.

UserIDFromContext
func (a *Auth) UserIDFromContext(ctx context.Context) (string, bool)

Reads the user id that Protected stored in the request context; the bool reports whether it was there.

Development

cmd/main.go is an example server that mounts the package the way a consuming service would, with CORS, a health route, and a protected test route. It reads DB_CONNECTION_STRING, CORS_ORIGIN, REDIRECT_URL, TEST_CLIENT_ID, and TEST_CLIENT_SECRET from a .env file (or the environment).

With Go, Postgres, and golangci-lint installed:

make dev     # run the example server on :8080
make lint    # lint the package

Project structure

tideauth/
├── tideauth.go       the package: Config, New, Migrate, Routes, Protected,
│                     and UserIDFromContext
├── cmd/              an example server that mounts the package
└── internal/
    ├── auth/         Google OAuth2/OIDC, session handlers, and middleware
    ├── httpx/        HTTP client and JSON response helpers
    └── migrations/   SQL migrations for the user data tables

License

See LICENSE.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Auth

type Auth struct {
	// contains filtered or unexported fields
}

func New

func New(cfg Config) *Auth

func (*Auth) Migrate

func (a *Auth) Migrate(ctx context.Context) error

func (*Auth) Protected

func (a *Auth) Protected(next http.HandlerFunc) http.HandlerFunc

func (*Auth) Routes

func (a *Auth) Routes() (http.Handler, error)

func (*Auth) UserIDFromContext added in v1.3.0

func (a *Auth) UserIDFromContext(ctx context.Context) (string, bool)

type Config

type Config struct {
	DB           *pgxpool.Pool
	CookieDomain string
	Google       Google
}

type Google

type Google struct {
	ClientID     string
	ClientSecret string
	RedirectURL  string
}

Directories

Path Synopsis
cmd
internal

Jump to

Keyboard shortcuts

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