goauthx

package module
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Nov 27, 2025 License: MIT Imports: 8 Imported by: 0

README

goauthx

A comprehensive, production-ready authentication and authorization library for Go. Framework-agnostic, supports multiple databases (MySQL, PostgreSQL, SQL Server), and provides JWT-based authentication with role-based access control (RBAC).

Features

  • User Authentication: Registration, login, logout, and password management
  • JWT Tokens: Secure access tokens with refresh token support
  • Google OAuth: Sign in with Google account integration
  • Role-Based Access Control (RBAC): Flexible roles and permissions system
  • Email Verification: Built-in email verification system
  • Password Reset: Secure password reset with tokens
  • Pre-built HTTP Handlers: Ready-to-use REST API handlers
  • Configurable Routes: Customize API endpoint paths
  • Multiple Database Support: MySQL, PostgreSQL, and SQL Server
  • Framework Agnostic: Works with net/http, Echo, Fiber, Gin, and others
  • Production Ready: Comprehensive error handling, logging, and testing
  • Migration System: Built-in database migration tool
  • Middleware Support: Ready-to-use HTTP middleware for authentication and authorization

Quick Start

Installation
go get github.com/devchuckcamp/goauthx
Basic Usage
package main

import (
	"context"
	"log"
	"time"

	"github.com/devchuckcamp/goauthx"
)

func main() {
	// 1. Configure the library
	cfg := goauthx.DefaultConfig()
	cfg.Database = goauthx.DatabaseConfig{
		Driver: goauthx.Postgres,
		DSN:    "postgres://user:password@localhost:5432/authdb?sslmode=disable",
	}
	cfg.JWT.Secret = "your-super-secret-jwt-key-min-32-chars-long"
	
	// 2. Create the store
	store, err := goauthx.NewStore(cfg.Database)
	if err != nil {
		log.Fatal(err)
	}
	defer store.Close()
	
	// 3. Run migrations
	migrator := goauthx.NewMigrator(store, cfg.Database.Driver)
	if err := migrator.Up(context.Background()); err != nil {
		log.Fatal(err)
	}
	
	// 4. Create the auth service
	authService, err := goauthx.NewService(cfg, store)
	if err != nil {
		log.Fatal(err)
	}
	
	// 5. Register a user
	resp, err := authService.Register(context.Background(), goauthx.RegisterRequest{
		Email:     "user@example.com",
		Password:  "securepassword123",
		FirstName: "John",
		LastName:  "Doe",
	})
	if err != nil {
		log.Fatal(err)
	}
	
	log.Printf("User registered: %s", resp.User.Email)
	log.Printf("Access token: %s", resp.AccessToken)
}
Running Migrations

Use the CLI tool to manage database migrations:

# Build the migration tool
cd cmd/goauthx-migrate
go build

# Apply migrations
./goauthx-migrate --dsn "postgres://user:pass@localhost/dbname?sslmode=disable" --driver postgres up

# Check migration status
./goauthx-migrate --dsn "..." --driver postgres status

# Rollback last migration
./goauthx-migrate --dsn "..." --driver postgres down
Using Pre-built HTTP Handlers
package main

import (
	"context"
	"log"
	"net/http"
	"github.com/devchuckcamp/goauthx"
)

func main() {
	// Setup configuration, store, and service...
	cfg := goauthx.DefaultConfig()
	// ... configure database and JWT settings ...
	
	store, _ := goauthx.NewStore(cfg.Database)
	defer store.Close()
	
	// Run migrations
	migrator := goauthx.NewMigrator(store, cfg.Database.Driver)
	migrator.Up(context.Background())
	
	authService, _ := goauthx.NewService(cfg, store)
	
	// Create HTTP handlers with default routes
	mux := http.NewServeMux()
	handlers := goauthx.NewHandlers(authService, nil)
	handlers.RegisterRoutes(mux)
	
	// All authentication endpoints are now available:
	// POST /auth/register
	// POST /auth/login
	// POST /auth/logout (authenticated)
	// POST /auth/refresh
	// GET  /auth/profile (authenticated)
	// POST /auth/change-password (authenticated)
	// POST /auth/forgot-password
	// POST /auth/reset-password
	// POST /auth/verify-email
	// POST /auth/resend-verification (authenticated)
	// GET  /auth/google - Google OAuth login
	// GET  /auth/google/callback - Google OAuth callback
	// POST /auth/google/unlink - Unlink Google account (authenticated)
	
	http.ListenAndServe(":8080", mux)
}
Using Custom Routes
// Customize endpoint paths
routeConfig := goauthx.DefaultRouteConfig()
routeConfig.RegisterPath = "/api/v1/register"
routeConfig.LoginPath = "/api/v1/login"
routeConfig.ProfilePath = "/api/v1/me"

handlers := goauthx.NewHandlers(authService, routeConfig)
handlers.RegisterRoutes(mux)
Using Custom Middleware
package main

import (
	"net/http"
	"github.com/devchuckcamp/goauthx"
)

func main() {
	// Setup (cfg, store, authService)...
	
	authMiddleware := goauthx.NewAuthMiddleware(authService)
	
	mux := http.NewServeMux()
	
	// Use pre-built handlers for auth endpoints
	handlers := goauthx.NewHandlers(authService, nil)
	handlers.RegisterRoutes(mux)
	
	// Add custom protected routes
	mux.Handle("/api/profile", authMiddleware.Authenticate(
		http.HandlerFunc(profileHandler),
	))
	
	// Admin only routes
	mux.Handle("/api/admin", authMiddleware.Authenticate(
		authMiddleware.RequireRole("admin")(
			http.HandlerFunc(adminHandler),
		),
	))
	
	http.ListenAndServe(":8080", mux)
}

Supported Databases

PostgreSQL
cfg.Database = goauthx.DatabaseConfig{
	Driver: goauthx.Postgres,
	DSN:    "postgres://user:password@localhost:5432/dbname?sslmode=disable",
}
MySQL
cfg.Database = goauthx.DatabaseConfig{
	Driver: goauthx.MySQL,
	DSN:    "user:password@tcp(localhost:3306)/dbname?parseTime=true",
}
SQL Server
cfg.Database = goauthx.DatabaseConfig{
	Driver: goauthx.SQLServer,
	DSN:    "sqlserver://user:password@localhost:1433?database=dbname",
}

Configuration

Full Configuration Example
cfg := &goauthx.Config{
	Database: goauthx.DatabaseConfig{
		Driver:          goauthx.Postgres,
		DSN:             "postgres://...",
		MaxOpenConns:    25,
		MaxIdleConns:    5,
		ConnMaxLifetime: 5 * time.Minute,
	},
	JWT: goauthx.JWTConfig{
		Secret:            "your-secret-min-32-chars",
		AccessTokenExpiry: 15 * time.Minute,
		Issuer:            "my-app",
		Audience:          "my-app-users",
	},
	Password: goauthx.PasswordConfig{
		MinLength:  8,
		BcryptCost: 12,
	},
	Token: goauthx.TokenConfig{
		RefreshTokenExpiry: 7 * 24 * time.Hour, // 7 days
		RefreshTokenLength: 64,
	},
	OAuth: goauthx.OAuthConfig{
		Google: goauthx.GoogleOAuthConfig{
			:     "your-google-client-id",
			ClientSecret: "your-google-client-secret",
			RedirectURL:  "http://localhost:8080/auth/google/callback",
			Enabled:      true,
		},
	},
}

Google OAuth Integration

Setup
  1. Get Google OAuth Credentials:

    • Go to Google Cloud Console
    • Create a new project or select existing one
    • Enable Google+ API
    • Go to "Credentials" → "Create Credentials" → "OAuth 2.0 Client ID"
    • Add authorized redirect URIs (e.g., http://localhost:8080/auth/google/callback)
    • Copy Client ID and Client Secret
  2. Configure goauthx:

cfg := goauthx.DefaultConfig()
cfg.OAuth.Google.ClientId = "your-client-id"
cfg.OAuth.Google.ClientSecret = "your-client-secret"
cfg.OAuth.Google.RedirectURL = "http://localhost:8080/auth/google/callback"
cfg.OAuth.Google.Enabled = true
  1. Using Pre-built Handlers (Recommended):
handlers := goauthx.NewHandlers(authService, nil)
handlers.RegisterRoutes(mux)

// OAuth endpoints are automatically available:
// GET  /auth/google - Initiates Google OAuth flow
// GET  /auth/google/callback - Handles OAuth callback
// POST /auth/google/unlink - Unlinks Google account (authenticated)
Usage Flows

New User Registration via Google:

  1. User clicks "Sign in with Google"
  2. Redirect to /auth/google
  3. User authenticates with Google
  4. Google redirects to /auth/google/callback
  5. New user account is automatically created
  6. User receives JWT access and refresh tokens

Existing User Login via Google:

  1. User with existing account clicks "Sign in with Google"
  2. OAuth flow completes
  3. Google account is linked to existing user
  4. User receives JWT tokens

Linking Google to Existing Account:

  • Users can link their Google account after registration
  • If email matches, accounts are automatically linked
  • Email is marked as verified if Google account is verified
Testing
# Start OAuth flow
curl http://localhost:8080/auth/google
# User will be redirected to Google login page

# After authentication, Google redirects to callback with tokens
# Response includes JWT access token and refresh token

# Unlink Google account (requires authentication)
curl -X POST http://localhost:8080/auth/google/unlink \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"account_id": "oauth-account-id"}'
Security Features
  • CSRF Protection: State parameter for OAuth flow
  • Account Linking: Prevents duplicate accounts
  • Password Optional: Users can sign up with only Google
  • Safe Unlinking: Can't unlink last auth method
  • Token Management: Automatic OAuth token refresh

Core Concepts

Authentication
  • Register: Create new user accounts with email and password
  • Login: Authenticate users and issue JWT access tokens
  • Logout: Revoke refresh tokens
  • Refresh: Generate new access tokens using refresh tokens
Authorization
  • Roles: Group permissions (e.g., "admin", "user", "moderator")
  • Permissions: Granular access control (e.g., "posts:read", "posts:write")
  • User-Role Assignment: Users can have multiple roles
  • Role-Permission Assignment: Roles can have multiple permissions
Checking Permissions
// Check if user has a role
hasRole, err := authService.HasRole(ctx, userID, "admin")

// Check if user has a permission
hasPerm, err := authService.HasPermission(ctx, userID, "posts:write")

// Get all user permissions
permissions, err := authService.GetUserPermissions(ctx, userID)
Email Verification
// During registration, create verification token
token, err := authService.ResendVerificationEmail(ctx, userID)
// In production: send token via email to user

// User verifies email with token
err := authService.VerifyEmail(ctx, token)
Password Reset
// User requests password reset
token, err := authService.RequestPasswordReset(ctx, "user@example.com")
// In production: send token via email to user

// User resets password with token
err := authService.ResetPassword(ctx, goauthx.ResetPasswordRequest{
	Token:       token,
	NewPassword: "newSecurePassword123",
})
Change Password
// User changes password (requires authentication)
err := authService.ChangePassword(ctx, userID, goauthx.ChangePasswordRequest{
	OldPassword: "currentPassword",
	NewPassword: "newSecurePassword123",
})

Testing with Docker

Quick Start with Docker PostgreSQL
  1. Start the PostgreSQL database:
docker-compose up -d

This will start a PostgreSQL 16 container with:

  • Database: authdb
  • User: authdb
  • Password: authdb
  • Port: 5432
  1. Run the example application:
cd examples/with-handlers
go run main.go

The example app will automatically:

  • Connect to the database
  • Run all migrations
  • Start the HTTP server on :8080
  1. Test the API endpoints:

Register a new user:

curl -X POST http://localhost:8080/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "securepassword123",
    "first_name": "John",
    "last_name": "Doe"
  }'

Login:

curl -X POST http://localhost:8080/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "securepassword123"
  }'

Access protected profile (replace YOUR_TOKEN with the access_token from login):

curl -X GET http://localhost:8080/auth/profile \
  -H "Authorization: Bearer YOUR_TOKEN"

Change password (authenticated):

curl -X POST http://localhost:8080/auth/change-password \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "old_password": "securepassword123",
    "new_password": "newSecurePassword456"
  }'

Request password reset:

curl -X POST http://localhost:8080/auth/forgot-password \
  -H "Content-Type: application/json" \
  -d '{"email": "user@example.com"}'

Reset password with token:

curl -X POST http://localhost:8080/auth/reset-password \
  -H "Content-Type: application/json" \
  -d '{
    "token": "RESET_TOKEN_FROM_EMAIL",
    "new_password": "newSecurePassword456"
  }'
  1. Stop the database:
docker-compose down

For more Docker commands and troubleshooting, see DOCKER.md.

Examples

See the examples/ directory for a complete working example:

  • examples/with-handlers/ - Complete example using pre-built HTTP handlers

Documentation

For detailed documentation, see the docs/ directory:

License

MIT License - see LICENSE for details

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Support

For issues and questions, please open an issue on GitHub.

Documentation

Overview

Package goauthx provides a comprehensive authentication and authorization library for Go

Index

Constants

View Source
const (
	MySQL     = config.MySQL
	Postgres  = config.Postgres
	SQLServer = config.SQLServer
)

Database drivers

View Source
const (
	UserIDKey    = middleware.UserIDKey
	UserEmailKey = middleware.UserEmailKey
	UserRolesKey = middleware.UserRolesKey
	ClaimsKey    = middleware.ClaimsKey
)

Context keys

View Source
const (
	OAuthProviderGoogle = models.OAuthProviderGoogle
)

OAuth providers

Variables

View Source
var (
	ErrInvalidCredentials  = auth.ErrInvalidCredentials
	ErrUserNotFound        = auth.ErrUserNotFound
	ErrUserInactive        = auth.ErrUserInactive
	ErrEmailAlreadyExists  = auth.ErrEmailAlreadyExists
	ErrInvalidRefreshToken = auth.ErrInvalidRefreshToken
	ErrPermissionDenied    = auth.ErrPermissionDenied
)

Common errors

View Source
var (
	GetUserID    = middleware.GetUserID
	GetUserEmail = middleware.GetUserEmail
	GetUserRoles = middleware.GetUserRoles
	GetClaims    = middleware.GetClaims
	Chain        = middleware.Chain
)

Helper functions from middleware package

Functions

This section is empty.

Types

type AuthMiddleware

type AuthMiddleware = middleware.AuthMiddleware

Re-export commonly used types for convenience

func NewAuthMiddleware

func NewAuthMiddleware(service *Service) *AuthMiddleware

NewAuthMiddleware creates a new authentication middleware

type AuthResponse

type AuthResponse = auth.AuthResponse

Re-export commonly used types for convenience

type ChangePasswordRequest

type ChangePasswordRequest = auth.ChangePasswordRequest

Re-export commonly used types for convenience

type Config

type Config = config.Config

Re-export commonly used types for convenience

func DefaultConfig

func DefaultConfig() *Config

DefaultConfig returns a configuration with sensible defaults

type ContextKey

type ContextKey = middleware.ContextKey

Re-export commonly used types for convenience

type DatabaseConfig

type DatabaseConfig = config.DatabaseConfig

Re-export commonly used types for convenience

type DatabaseDriver

type DatabaseDriver = config.DatabaseDriver

Re-export commonly used types for convenience

type EmailVerification

type EmailVerification = models.EmailVerification

Re-export commonly used types for convenience

type GoogleOAuthCallbackRequest

type GoogleOAuthCallbackRequest = auth.GoogleOAuthCallbackRequest

Re-export commonly used types for convenience

type GoogleOAuthConfig

type GoogleOAuthConfig = config.GoogleOAuthConfig

Re-export commonly used types for convenience

type GoogleOAuthURLRequest

type GoogleOAuthURLRequest = auth.GoogleOAuthURLRequest

Re-export commonly used types for convenience

type GoogleUserInfo

type GoogleUserInfo = models.GoogleUserInfo

Re-export commonly used types for convenience

type Handlers

type Handlers = handlers.Handlers

Re-export commonly used types for convenience

func NewHandlers

func NewHandlers(service *Service, routeConfig *RouteConfig) *Handlers

NewHandlers creates new HTTP handlers

type JWTConfig

type JWTConfig = config.JWTConfig

Re-export commonly used types for convenience

type LoginRequest

type LoginRequest = auth.LoginRequest

Re-export commonly used types for convenience

type Migrator

type Migrator = migrations.Migrator

Re-export commonly used types for convenience

func NewMigrator

func NewMigrator(store Store, driver DatabaseDriver) *Migrator

NewMigrator creates a new migrator

type OAuthAccount

type OAuthAccount = models.OAuthAccount

Re-export commonly used types for convenience

type OAuthConfig

type OAuthConfig = config.OAuthConfig

Re-export commonly used types for convenience

type OAuthProvider

type OAuthProvider = models.OAuthProvider

Re-export commonly used types for convenience

type PasswordConfig

type PasswordConfig = config.PasswordConfig

Re-export commonly used types for convenience

type PasswordReset

type PasswordReset = models.PasswordReset

Re-export commonly used types for convenience

type Permission

type Permission = models.Permission

Re-export commonly used types for convenience

type RefreshToken

type RefreshToken = models.RefreshToken

Re-export commonly used types for convenience

type RefreshTokenRequest

type RefreshTokenRequest = auth.RefreshTokenRequest

Re-export commonly used types for convenience

type RegisterRequest

type RegisterRequest = auth.RegisterRequest

Re-export commonly used types for convenience

type RequestPasswordResetRequest

type RequestPasswordResetRequest = auth.RequestPasswordResetRequest

Re-export commonly used types for convenience

type ResetPasswordRequest

type ResetPasswordRequest = auth.ResetPasswordRequest

Re-export commonly used types for convenience

type Role

type Role = models.Role

Re-export commonly used types for convenience

type RouteConfig

type RouteConfig = config.RouteConfig

Re-export commonly used types for convenience

func DefaultRouteConfig

func DefaultRouteConfig() *RouteConfig

DefaultRouteConfig returns route configuration with sensible defaults

type Service

type Service = auth.Service

Re-export commonly used types for convenience

func NewService

func NewService(cfg *Config, store Store) (*Service, error)

NewService creates a new authentication service

type Store

type Store = store.Store

Re-export commonly used types for convenience

func NewStore

func NewStore(cfg DatabaseConfig) (Store, error)

NewStore creates a new SQL store

type TokenConfig

type TokenConfig = config.TokenConfig

Re-export commonly used types for convenience

type User

type User = models.User

Re-export commonly used types for convenience

type VerifyEmailRequest

type VerifyEmailRequest = auth.VerifyEmailRequest

Re-export commonly used types for convenience

Directories

Path Synopsis
cmd
goauthx-migrate command
examples
with-handlers command
pkg

Jump to

Keyboard shortcuts

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