go-pkgz/auth

repository·master·Indexed 23 days ago

https://github.com/go-pkgz/auth

A Go library providing comprehensive authentication capabilities, including OAuth2 social logins, direct credential authentication, email verification, and JWT management. It includes built-in middleware for authentication, admin access, and RBAC, as well as an automatic avatar proxy with support for LocalFS, BoltDB, and GridFS storage. The library supports custom OAuth2 providers and verified authentication flows.

Tokens
8.4K
Snippets
14
Records
38
Agent score
77%

What's inside go-pkgz/auth

  1. Understand the library versioning and status

    master

    The library was originally extracted from the remark42 project and is used in production across multiple sites.

    • Version 1.x: Stable and in maintenance mode.
    • Version 2.x: The actively developed branch. It is recommended for all new projects.
  2. Register OAuth2 Providers: Callback URL Patterns

    master

    When registering any OAuth2 provider (Google, Microsoft, GitHub, Facebook, Apple, Yandex, Battle.net, Patreon, Discord, or Twitter), you must provide a valid Authorized Redirect URI (or Callback URL).

    The pattern for the callback URL is always: [your-domain]/auth/[provider-name]/callback.

    Examples:

    • Google: https://example.com/auth/google/callback
    • GitHub: https://example.com/auth/github/callback
    • Discord: https://example.com/auth/discord/callback
  3. Protect against confirmation token replay in multi-instance deployments

    master

    By default, AddVerifProvider uses an in-memory store for confirmation tokens. This is only safe for single-instance deployments. In multi-instance environments (behind a load balancer), an attacker could replay a token on a different instance.

    To prevent this, provide a shared backend by setting Opts.VerifConfirmationStore with an implementation of the VerifConfirmationStore interface:

    type VerifConfirmationStore interface {
        // MarkUsed records key as consumed and returns alreadyUsed=true if it was
        // already recorded. err signals a backend failure -- callers fail-closed
        // (reject the redemption) on non-nil err to avoid replay during outages.
        MarkUsed(key string, ttl time.Duration) (alreadyUsed bool, err error)
    }
  4. Customize authentication behavior with hooks

    master

    The library provides several interfaces to adjust how tokens are created and validated:

    • SecretReader: Returns the secret used for JWT signing/verification based on the aud claim.
    • ClaimsUpdater: Primary way to alter a token at login (e.g., adding roles, email, or custom attributes).
    • Validator: A post-token hook called on every request wrapped with Auth middleware. Use this to reject specific users or tokens (e.g., blacklists).
    • UserUpdater: Called on every request wrapped with UpdateUser middleware to modify the User object in the request context.

    All interfaces have functional adapters: SecretFunc, ClaimsUpdFunc, ValidatorFunc, and UserUpdFunc.

  5. Secure browser apps with Cross-Origin Protection

    master

    For browser-based applications, it is recommended to pair the library's JWT XSRF check with Go 1.25+'s http.CrossOriginProtection.

    While the library's JWT XSRF check handles API clients sending JWT-derived headers, http.CrossOriginProtection provides a primary defense at the HTTP layer by checking the Sec-Fetch-Site header (or Origin vs Host fallback). This protects against cross-origin state-changing requests and blocks subdomain attacks that SameSite=Lax might miss.

    To use it, wrap your router with the http.CrossOriginProtection handler and configure trusted origins or bypass patterns for specific endpoints (like Apple Sign In).

    csrf := http.NewCrossOriginProtection()
    _ = csrf.AddTrustedOrigin("https://app.example.com") // for cross-origin SPAs
    csrf.AddInsecureBypassPattern("POST /auth/apple/")   // Apple Sign In uses form_post
    
    mux := http.NewServeMux()
    mux.Handle("/api/", authenticator.Auth(apiHandler))
    
    log.Fatal(http.ListenAndServe(":8080", csrf.Handler(mux)))
  6. Run the go-pkgz/auth example

    master

    To run the example application locally, execute the following command in your terminal:

    go run main.go

    Once running, you can access the following routes:

    • Open route: http://localhost:8080/open
    • Web application: http://localhost:8080/web
  7. Migrate from auth v1 to v2

    master

    The v2 version is the actively developed version and uses github.com/golang-jwt/jwt/v5. To migrate from v1 to v2:

    1. Update import paths to use /v2 (e.g., github.com/go-pkgz/auth/v2).
    2. Update custom code accessing token fields to use the new JWT v5 structures:
      • Replace StandardClaims with RegisteredClaims.
      • Update expiration, not before, and issued at fields from int64 to *jwt.NumericDate.
      • Rename Id field to ID.
      • Change Audience from string to []string.
    3. If implementing the RefreshCache interface, update the method signatures to use strongly typed values:
      • Get(key string) (value token.Claims, ok bool)
      • Set(key string, value token.Claims)
  8. Integrate auth service into your application

    master

    To add authentication support using the auth library, follow these steps:

    1. Configure Options: Initialize an auth.Opts struct with your required parameters (most are optional with sane defaults).
    2. Create Service: Instantiate a new auth.Service using the provided options.
    3. Add Providers: Register your desired authentication providers (e.g., OAuth2, Direct, or Verified).
    4. Retrieve Handlers: Get the necessary middleware and http handlers from the auth.Service instance.
    5. Wire Routes: Register the auth and avatar handlers into your HTTP router as sub-routes (e.g., /auth and /avatar).
  9. Configure Apple Auth Provider

    master

    Apple authentication requires an Apple Developer account and a configured Service ID.

    Configuration Steps

    1. Create an App ID and enable "Sign in with Apple".
    2. Create a Service ID and bind it to the App ID. The Service ID acts as the ClientID.
    3. Generate a private key and download it. Note the KeyID.
    4. Add your domain and sender email in the Apple Developer portal.

    Implementation

    You must provide an AppleConfig and a PrivateKeyLoaderInterface. The provider.LoadApplePrivateKeyFromFile helper is recommended for loading the downloaded key.

    Note on User Info: Apple only sends the userName (if requested) during the initial sign-up. Subsequent logins only return the user identifier in the IDToken. It is recommended to securely cache user info during the first login to bind it to a permanent UID.

    // apple config parameters
    appleCfg := provider.AppleConfig{
    	TeamID: os.Getenv("AEXMPL_APPLE_TID"), // developer account identifier
    	ClientID: os.Getenv("AEXMPL_APPLE_CID"), // Service ID (or App ID)
    	KeyID: os.Getenv("AEXMPL_APPLE_KEYID"), // private key identifier
    }
    
    if err := service.AddAppleProvider(appleCfg, provider.LoadApplePrivateKeyFromFile("PATH_TO_PRIVATE_KEY_FILE")); err != nil {
    	log.Fatalf("[ERROR] failed create to AppleProvider: %v", err)
    }
  10. Configure GitHub provider for the example

    master

    The example does not require command line parameters. However, to enable the GitHub authentication provider, you must define the following environment variables:

    • AEXMPL_GITHUB_CID: Your GitHub Client ID
    • AEXMPL_GITHUB_CSEC: Your GitHub Client Secret

    For detailed configuration of the GitHub provider, refer to the main repository documentation at https://github.com/go-pkgz/auth#github-auth-provider.

  11. Configure the Avatar Proxy

    master

    To prevent throttling from providers (like Google or GitHub) when many users view avatars, auth provides an automatic proxy. On login, the library retrieves the user's picture and saves it to an AvatarStore.

    Setup via auth.Opts:

    • AvatarStore: Choose a storage implementation:
      • avatar.LocalFS: File system (e.g., avatar.NewLocalFS("/tmp/avatars") or file:///tmp/location).
      • avatar.BoltDB: Embedded KV store (e.g., bolt://tmp/avatars.bdb).
      • avatar.GridFS: MongoDB GridFS (e.g., "mongodb://127.0.0.1:27017/test?ava_db=db1&ava_coll=coll1").
    • AvatarRoutePath: The route prefix for direct links (e.g., /api/v1/avatars). This makes links look like http://example.com/api/v1/avatars/1234567890123.image.
    • AvatarResizeLimit: Size in pixels for resizing. Set to 0 (default) to disable resizing.