### Install go-pkgz/auth Source: https://github.com/go-pkgz/auth/blob/master/README.md Install the go-pkgz/auth library using go get. ```bash go get -u github.com/go-pkgz/auth/v2 ``` -------------------------------- ### Complete Avatar Service Integration Example Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/api-reference/avatar.md A comprehensive example demonstrating the setup of the avatar service, including storage, routing, resizing, and integration with authentication middleware and routes. ```go package main import ( "fmt" "github.com/go-pkgz/auth" "github.com/go-pkgz/auth/avatar" "github.com/go-pkgz/auth/token" "net/http" ) func main() { // Setup avatar store store := avatar.NewLocalFS("/var/avatars") // Setup service with avatar configuration opts := auth.Opts{ SecretReader: token.SecretFunc(func(aud string) (string, error) { return "secret", nil }), URL: "https://example.com", AvatarStore: store, AvatarRoutePath: "/api/v1/avatars", AvatarResizeLimit: 256, } service := auth.NewService(opts) service.AddProvider("github", "client-id", "client-secret") // Setup routes router := http.NewServeMux() authRoutes, avatarRoutes := service.Handlers() router.Handle("/auth/", http.StripPrefix("/auth", authRoutes)) router.Handle("/avatar/", http.StripPrefix("/avatar", avatarRoutes)) // Protected route accessing avatar m := service.Middleware() router.Handle("GET /profile", m.Auth( http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { user := token.MustGetUserInfo(r) w.Header().Set("Content-Type", "application/json") fmt.Fprintf(w, `{"name":"%s","avatar":"%s"}`, user.Name, user.Picture) }), )) http.ListenAndServe(":8080", router) } ``` -------------------------------- ### Add Apple Provider Example Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/api-reference/providers.md Example demonstrating how to configure Apple Sign In with a specific configuration and load the private key from a file. It then adds the provider to the service. ```go appleCfg := provider.AppleConfig{ TeamID: "ABC123DEFG", ClientID: "com.example.service", KeyID: "ABC123XYZ", } if err := service.AddAppleProvider(appleCfg, provider.LoadApplePrivateKeyFromFile("key.p8")); err != nil { log.Fatal(err) } ``` -------------------------------- ### Custom Basic Authentication Example Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/api-reference/middleware.md An example of implementing a custom BasicAuthFunc to verify credentials against a database and populate user information. ```go opts := auth.Opts{ BasicAuthChecker: func(user, passwd string) (ok bool, userInfo token.User, err error) { // Check against LDAP or database if db.VerifyPassword(user, passwd) { roles, _ := db.GetRoles(user) return true, token.User{ ID: user, Name: user, Role: strings.Join(roles,","), }, nil } return false, token.User{}, errors.New("invalid credentials") }, } ``` -------------------------------- ### Email Sender Example Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/api-reference/providers.md Demonstrates how to initialize and use the EmailClient to send emails. This example sets up a Gmail SMTP client and adds it as an email verification provider. ```go import "github.com/go-pkgz/auth/provider/sender" emailSender := sender.NewEmailClient(sender.EmailParams{ Host: "smtp.gmail.com", Port: 587, SMTPUserName: "user@gmail.com", SMTPPassword: "app-password", StartTLS: true, From: "noreply@example.com", Subject: "Confirmation", }, logger.Std) service.AddVerifProvider("email", "Confirm: {{.Token}}", emailSender) ``` -------------------------------- ### Complete Auth Service Example Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/api-reference/middleware.md A full example demonstrating the initialization of the Auth service, adding providers, setting up middleware, and defining routes for public, authenticated, admin-only, and role-based access. ```go package main import ( "github.com/go-pkgz/auth" "github.com/go-pkgz/auth/avatar" "github.com/go-pkgz/auth/token" "net/http" "time" ) func main() { // Initialize service opts := auth.Opts{ SecretReader: token.SecretFunc(func(aud string) (string, error) { return "my-secret", nil }), URL: "http://localhost:8080", AvatarStore: avatar.NewLocalFS("/tmp/avatars"), Logger: logger.Std, } service := auth.NewService(opts) service.AddProvider("github", "client-id", "client-secret") // Get middleware m := service.Middleware() // Setup router router := http.NewServeMux() // Public route router.HandleFunc("GET /", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte("Welcome")) }) // Authenticated route router.Handle("GET /profile", m.Auth( http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { user := token.MustGetUserInfo(r) w.WriteHeader(http.StatusOK) w.Write([]byte("Profile: " + user.Name)) }), )) // Admin-only route router.Handle("POST /admin", m.Admin( http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte("Admin panel")) }), )) // Role-based route router.Handle("POST /articles", m.RBAC("editor", "admin")( http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { user := token.MustGetUserInfo(r) w.WriteHeader(http.StatusOK) w.Write([]byte("Editor: " + user.Name)) }), )) // Auth handlers authRoutes, avatarRoutes := service.Handlers() router.Handle("/auth/", http.StripPrefix("/auth", authRoutes)) router.Handle("/avatar/", http.StripPrefix("/avatar", avatarRoutes)) // Start server http.ListenAndServe(":8080", router) } ``` -------------------------------- ### Usage with Chi Router Source: https://github.com/go-pkgz/auth/blob/master/README.md Example demonstrating integration with the chi router for authentication. This setup is similar to the routegroup example but uses chi's specific methods for middleware and route handling. Ensure chi is imported. ```go func main() { // define options options := auth.Opts{ SecretReader: token.SecretFunc(func(id string) (string, error) { // secret key for JWT return "secret", nil }), TokenDuration: time.Minute * 5, // token expires in 5 minutes CookieDuration: time.Hour * 24, // cookie expires in 1 day and will enforce re-login Issuer: "my-test-app", URL: "http://127.0.0.1:8080", AvatarStore: avatar.NewLocalFS("/tmp"), Validator: token.ValidatorFunc(func(_ string, claims token.Claims) bool { // allow only dev_* names return claims.User != nil && strings.HasPrefix(claims.User.Name, "dev_") }), } // create auth service with providers service := auth.NewService(options) service.AddProvider("github", "", "") // add github provider service.AddProvider("facebook", "", "") // add facebook provider // retrieve auth middleware m := service.Middleware() // setup http server router := chi.NewRouter() router.Get("/open", openRouteHandler) // open api router.With(m.Auth).Get("/private", protectedRouteHandler) // protected api // setup auth routes authRoutes, avaRoutes := service.Handlers() router.Mount("/auth", authRoutes) // add auth handlers router.Mount("/avatar", avaRoutes) // add avatar handler log.Fatal(http.ListenAndServe(":8080", router)) } ``` -------------------------------- ### Telegram Provider Initialization Example Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/api-reference/providers.md Example demonstrating how to initialize and configure the TelegramHandler, including setting up the Telegram API, token service, and avatar saver. The handler is then added to the service. ```go import "os" telegramHandler := provider.TelegramHandler{ ProviderName: "telegram", SuccessMsg: "✅ Successfully authenticated!", ErrorMsg: "❌ Authentication failed", Telegram: provider.NewTelegramAPI(os.Getenv("TELEGRAM_TOKEN"), http.DefaultClient), TokenService: service.TokenService(), AvatarSaver: service.AvatarProxy(), L: logger.Std, } // Run handler in background go func() { if err := telegramHandler.Run(context.Background()); err != nil { log.Fatal(err) } }() service.AddCustomHandler(&telegramHandler) ``` -------------------------------- ### Apple Sign In Response Example Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/endpoints.md Example JSON response after a successful Apple Sign In. Includes basic user information and audience. ```json { "user": { "name": "Jane Doe", "id": "apple_", "aud": "myapp" } } ``` -------------------------------- ### User Data Mapping Function Example Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/types.md Provides an example of a function to map UserData from a provider into a token.User structure. It uses the Value accessor for retrieving fields. ```go func mapUser(data provider.UserData, _ []byte) token.User { return token.User{ Name: data.Value("name"), ID: "prefix_" + data.Value("id"), } } ``` -------------------------------- ### Typical Auth Service Setup in Go Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/00-START-HERE.md Illustrates the common steps to initialize the auth service, configure options, add providers, and set up middleware and handlers for route protection. ```go // 1. Create options opts := auth.Opts{ SecretReader: token.SecretFunc(func(aud string) (string, error) { return "my-secret-key", nil }), URL: "https://example.com", AvatarStore: avatar.NewLocalFS("/tmp/avatars"), } // 2. Initialize service service := auth.NewService(opts) // 3. Add authentication providers service.AddProvider("github", os.Getenv("GITHUB_CLIENT_ID"), os.Getenv("GITHUB_CLIENT_SECRET")) // 4. Get middleware for route protection m := service.Middleware() // 5. Mount handlers authRoutes, avatarRoutes := service.Handlers() router.Handle("/auth/", http.StripPrefix("/auth", authRoutes)) router.Handle("/avatar/", http.StripPrefix("/avatar", avatarRoutes)) // 6. Protect routes router.Handle("GET /protected", m.Auth(handler)) ``` -------------------------------- ### Configure Confirmation Store with Redis Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/api-reference/providers.md Example of configuring the verification provider to use a Redis store for token consumption. ```go opts := auth.Opts{ VerifConfirmationStore: myRedisStore, } ``` -------------------------------- ### Verify Provider Login Endpoint URL (GET with token) Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/types.md Example GET request URL for verifying a provider login using a confirmation token. ```http GET /auth//login?token=&sess=[0|1] ``` -------------------------------- ### Direct Provider Login Endpoint URL (GET) Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/types.md Example GET request URL for direct provider login, including user credentials and site ID. ```http GET /auth//login?user=&passwd=&aud=&sess=[0|1] ``` -------------------------------- ### Set up and Run a Custom OAuth2 Server Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/api-reference/providers.md Example of initializing and running a custom OAuth2 server for local development. It configures the server with a login page and registers it with the authentication service. ```go sopts := provider.CustomServerOpt{ URL: "http://127.0.0.1:9096", WithLoginPage: true, } customSrv := provider.NewCustomServer(oauth2Server, sopts) go func() { if err := customSrv.Run(context.Background()); err != nil { log.Fatal(err) } }() service.AddCustomProvider("custom", auth.Client{Cid: "cid", Csecret: "secret"}, customSrv.HandlerOpt) ``` -------------------------------- ### Example User Mapping Function Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/api-reference/providers.md Demonstrates how to map UserData from an OAuth2 provider response to a token.User struct. ```go func mapUser(data provider.UserData, _ []byte) token.User { return token.User{ ID: data.Value("sub"), Name: data.Value("name"), Picture: data.Value("picture"), } } ``` -------------------------------- ### Provider Registration Examples Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/api-reference/providers.md Shows various methods for registering different types of authentication providers with a service. Providers are accessible via /auth//login routes. ```go service := auth.NewService(opts) service.AddProvider("github", "id", "secret") service.AddProvider("google", "id", "secret") service.AddDirectProvider("local", checker) service.AddVerifProvider("email", template, sender) service.AddCustomProvider("bitbucket", client, opts) service.AddAppleProvider(cfg, loader) service.AddDevProvider("127.0.0.1", 8084) service.AddCustomHandler(myProvider) ``` -------------------------------- ### Direct Login Response (JSON) Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/endpoints.md Example JSON response upon successful direct login. ```json { "user": { "name": "username", "id": "provider_", "aud": "site_id" } } ``` -------------------------------- ### Configure Provider with Environment Variables Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/configuration.md Example of configuring a provider using environment variables for sensitive credentials like client ID and secret. Ensure necessary imports are present. ```go import "os" clientID := os.Getenv("GITHUB_CLIENT_ID") clientSecret := os.Getenv("GITHUB_CLIENT_SECRET") service.AddProvider("github", clientID, clientSecret) ``` -------------------------------- ### OAuth2 Callback Response Example (JSON) Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/endpoints.md Example JSON response upon successful OAuth2 callback when the response is not a redirect. Includes user information. ```json { "user": { "name": "John Doe", "id": "github_", "picture": "https://example.com/avatar/xxx.image", "aud": "myapp" } } ``` -------------------------------- ### Login via GET Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/endpoints.md Authenticates a user using GET request with username and password. It can optionally set session tokens and site IDs. ```APIDOC ## GET /auth//login ### Description Authenticates a user via GET request using username and password. Supports optional site ID and session token generation. ### Method GET ### Endpoint /auth//login ### Parameters #### Query Parameters - **user** (string) - Required - Username - **passwd** (string) - Required - Password or hash - **aud** (string) - Optional - Site ID - **sess** (enum) - Optional - If "1", session-only token ### Response #### Success Response HTTP 302 redirect or HTTP 200 JSON with user info #### Failure Response HTTP 403 JSON error ``` -------------------------------- ### Direct Login via GET Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/endpoints.md Initiates a login request using username and password via HTTP GET. Supports optional site ID and session-only token. ```http GET /auth//login?user=&passwd=&aud=&sess=[0|1] ``` -------------------------------- ### Complete Error Handler Setup Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/errors.md Illustrates a comprehensive error handling strategy for an authentication service. This includes setting up options for secret reading, token validation, and a custom JSON error response handler. ```go func protectedRoute(w http.ResponseWriter, r *http.Request) { user, err := token.GetUserInfo(r) if err != nil { // User middleware already rejected, but here for safety http.Error(w, "Unauthorized", http.StatusUnauthorized) return } // User is authenticated w.WriteHeader(http.StatusOK) fmt.Fprintf(w, "Hello, %s", user.Name) } func main() { opts := auth.Opts{ SecretReader: token.SecretFunc(func(aud string) (string, error) { // Handle secret reader errors secret, err := db.GetSecret(aud) if err != nil { log.Printf("[ERROR] secret reader failed: %v", err) return "", err } return secret, nil }), Validator: token.ValidatorFunc(func(token string, claims token.Claims) bool { // Handle validation errors if claims.User == nil { log.Printf("[WARN] token has no user info") return false } if db.IsBlacklisted(claims.User.ID) { log.Printf("[WARN] user %s is blacklisted", claims.User.ID) return false } return true }), ErrorHandler: middleware.ErrorHandlerFunc(func(w http.ResponseWriter, r *http.Request, code int, err error) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(code) json.NewEncoder(w).Encode(map[string]any{ "error": err.Error(), "code": code, }) }), } service := auth.NewService(opts) // ... rest of setup } ``` -------------------------------- ### Initialize Local OAuth2 Server Source: https://github.com/go-pkgz/auth/blob/master/README.md Configure and start a local OAuth2 server using custom options. This includes setting the server URL, logger, and whether to display a login page. ```go sopts := provider.CustomServerOpt{ URL: "http://127.0.0.1:9096", L: options.Logger, WithLoginPage: true, } prov := provider.NewCustomServer(srv, sopts) // Start server go prov.Run(context.Background()) ``` -------------------------------- ### Custom UserIDFunc Example Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/api-reference/providers.md Demonstrates how to provide a custom UserIDFunc to generate user IDs with a specific prefix, useful for distinguishing user sources. ```go idFunc := func(user string, r *http.Request) string { return "ldap_" + user } service.AddDirectProviderWithUserIDFunc("ldap", credChecker, idFunc) ``` -------------------------------- ### MustGetUserInfo Example Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/api-reference/token-service.md Extracts user information from the request context, panicking if it's not found. Use this when user presence is guaranteed. ```go user := token.MustGetUserInfo(r) fmt.Println(user.Name) ``` -------------------------------- ### SetUserInfo Example Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/api-reference/token-service.md Sets user information in the request context. This function returns a new request object with the updated context. ```go r = token.SetUserInfo(r, user) ``` -------------------------------- ### Example JSON Error: Invalid Credentials Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/endpoints.md Illustrates an error response when a user provides incorrect credentials. ```json { "error": "incorrect user or password", "code": "forbidden" } ``` -------------------------------- ### Usage with routegroup Router Source: https://github.com/go-pkgz/auth/blob/master/README.md Example demonstrating how to set up the auth service and integrate it with the routegroup router for handling protected and open API routes. Configure authentication options, add OAuth providers, and set up HTTP handlers. ```go func main() { // define options options := auth.Opts{ SecretReader: token.SecretFunc(func(id string) (string, error) { // secret key for JWT return "secret", nil }), TokenDuration: time.Minute * 5, // token expires in 5 minutes CookieDuration: time.Hour * 24, // cookie expires in 1 day and will enforce re-login Issuer: "my-test-app", URL: "http://127.0.0.1:8080", AvatarStore: avatar.NewLocalFS("/tmp"), Validator: token.ValidatorFunc(func(_ string, claims token.Claims) bool { // allow only dev_* names return claims.User != nil && strings.HasPrefix(claims.User.Name, "dev_") }), } // create auth service with providers service := auth.NewService(options) service.AddProvider("github", "", "") // add github provider service.AddProvider("facebook", "", "") // add facebook provider // retrieve auth middleware m := service.Middleware() // setup http server router := routegroup.New(http.NewServeMux()) router.HandleFunc("GET /open", openRouteHandler) // open api router.Group().Route(func(r *routegroup.Bundle) { r.Use(m.Auth) r.HandleFunc("GET /private", protectedRouteHandler) // protected api }) // setup auth routes authRoutes, avaRoutes := service.Handlers() router.Handle("/auth/", http.StripPrefix("/auth", authRoutes)) // add auth handlers router.Handle("/avatar/", http.StripPrefix("/avatar", avaRoutes)) // add avatar handler log.Fatal(http.ListenAndServe(":8080", router)) } ``` -------------------------------- ### Add Apple Provider with Private Key Loading Source: https://github.com/go-pkgz/auth/blob/master/README.md Add the Apple provider to your service, passing the AppleConfig and a PrivateKeyLoader. The example uses `provider.LoadApplePrivateKeyFromFile` to load the private key. Always check for errors during provider addition. ```go if err := service.AddAppleProvider(appleCfg, provider.LoadApplePrivateKeyFromFile("PATH_TO_PRIVATE_KEY_FILE")); err != nil { log.Fatalf("[ERROR] failed create to AppleProvider: %v", err) } ``` -------------------------------- ### Running the Development Auth Server Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/api-reference/service.md Start the development OAuth2 server in a goroutine if the 'dev' provider is registered. This is useful for local testing and development environments. ```go go func() { devServer, err := service.DevAuth() if err != nil { log.Fatal(err) } devServer.Run() }() ``` -------------------------------- ### Admin Basic Authentication with Curl Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/api-reference/middleware.md Example of how to use curl to authenticate with the admin credentials. Ensure the password matches the one set in Opts.AdminPasswd. ```bash curl -u admin:mypassword http://localhost:8080/protected ``` -------------------------------- ### Configure Logging Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/README.md Configures the Auth service to use a specific logger implementation. This example shows how to set the logger to standard output. ```go opts := auth.Opts{ Logger: logger.Std, // Log to stdout } ``` -------------------------------- ### Add Custom OAuth2 Provider (Bitbucket Example) Source: https://github.com/go-pkgz/auth/blob/master/README.md Use this to add a third-party OAuth2 provider. Requires client credentials, endpoint URLs, user info URL, a function to map user data, and necessary scopes. ```go c := auth.Client{ Cid: os.Getenv("AEXMPL_BITBUCKET_CID"), Csecret: os.Getenv("AEXMPL_BITBUCKET_CSEC"), } service.AddCustomProvider("bitbucket", c, provider.CustomHandlerOpt{ Endpoint: oauth2.Endpoint{ AuthURL: "https://bitbucket.org/site/oauth2/authorize", TokenURL: "https://bitbucket.org/site/oauth2/access_token", }, InfoURL: "https://api.bitbucket.org/2.0/user/", MapUserFn: func(data provider.UserData, _ []byte) token.User { userInfo := token.User{ ID: "bitbucket_" + token.HashID(sha1.New(), data.Value("username")), Name: data.Value("nickname"), } return userInfo }, Scopes: []string{"account"}, }) ``` -------------------------------- ### Run Dev OAuth2 Server in Go Source: https://github.com/go-pkgz/auth/blob/master/README.md Starts a development-only OAuth2 server. This is for testing and development purposes only and should not be used in production. ```go // runs dev oauth2 server on :8084 by default go func() { devAuthServer, err := service.DevAuth() if err != nil { log.Fatal(err) } devAuthServer.Run() }() ``` -------------------------------- ### Configure Auth Options with Allowed Redirect Hosts Source: https://github.com/go-pkgz/auth/blob/master/README.md Example of setting up `auth.Opts` to use a custom function for allowed redirect hosts. This hardens the authentication flow by restricting where users can be redirected. ```go opts := auth.Opts{ URL: "https://app.example.com", AllowedRedirectHosts: token.AllowedHostsFunc(func() ([]string, error) { return []string{"admin.example.com", "billing.example.com"}, nil }), // ... } ``` -------------------------------- ### Internal Logging Example Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/api-reference/logger.md This snippet shows how the auth library internally uses the Logf method if a logger is configured. You do not write this code directly. ```go if s.logger != nil { s.logger.Logf("[INFO] login with %s", providerName) } ``` -------------------------------- ### Run and Register Telegram Provider Source: https://github.com/go-pkgz/auth/blob/master/README.md Start the Telegram provider in a background goroutine and register its handlers with the authentication service. ```go // Run Telegram provider in the background go func() { err := telegram.Run(context.Background()) if err != nil { log.Fatalf("[PANIC] failed to start telegram: %v", err) } }() // Register Telegram provider service.AddCustomHandler(&telegram) ``` -------------------------------- ### Direct Provider Login Endpoint (POST) Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/types.md Example POST request for direct provider login, with session parameter. ```http POST /auth//login?sess=[0|1] ``` -------------------------------- ### User Attributes Mapping Example Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/types.md Demonstrates how to map provider field names to custom attribute names for user data. Used with AddProviderWithUserAttributes. ```go attrs := provider.UserAttributes{ "email": "user_email", "bio": "description", } service.AddProviderWithUserAttributes("github", cid, csecret, attrs) // User attributes: user.StrAttr("user_email"), user.StrAttr("description") ``` -------------------------------- ### GetUserInfo Example Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/api-reference/token-service.md Extracts user information from the request context. Ensure user info is set by middleware before calling this function. Returns an error if user info is not found. ```go user, err := token.GetUserInfo(r) if err != nil { log.Fatal(err) } fmt.Println(user.Name) ``` -------------------------------- ### Example: Credential Checker Failure Handling Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/errors.md Demonstrates how to handle potential errors returned from an LDAP connection during credential checking. Errors from ldap.Connect() are returned directly, leading to a 500 status. ```go checker := provider.CredCheckerFunc(func(user, passwd string) (bool, error) { conn, err := ldap.Connect() // ← returns error if err != nil { return false, err // → 500 } return conn.Verify(user, passwd) }) ``` -------------------------------- ### Configure Allowed Redirect Hosts Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/endpoints.md Example of configuring allowed redirect hosts using a custom function. The host from Opts.URL is always permitted. ```go opts := auth.Opts{ URL: "https://app.example.com", AllowedRedirectHosts: token.AllowedHostsFunc(func() ([]string, error) { return []string{"admin.example.com", "api.example.com"}, nil }), } ``` -------------------------------- ### Verify Provider Login Endpoint URL (GET with user/address) Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/types.md Example GET request URL for verifying a provider login using user credentials and address. ```http GET /auth//login?user=&address=
&aud=&from= ``` -------------------------------- ### Apple Sign In Login Request Body Example Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/endpoints.md The request body for initiating an Apple Sign In. It requires an 'id_token' obtained from Apple's authentication process. ```json { "id_token": "eyJhbGci..." } ``` -------------------------------- ### Add Valid and Invalid Providers Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/errors.md Demonstrates correct usage for adding providers with valid names and highlights examples of invalid names that trigger errors. ```go // Good service.AddProvider("github", cid, secret) service.AddCustomProvider("my-provider", client, opts) service.AddCustomProvider("my_provider_v1", client, opts) // Bad service.AddProvider("my:provider", cid, secret) // Contains ':' service.AddProvider("", cid, secret) // Empty name ``` -------------------------------- ### OAuth2 Login Request Example Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/endpoints.md Initiates an OAuth2 login flow for a specified provider. Use the 'from' parameter to specify the redirect URL after authentication. ```http GET /auth/github/login?from=https://example.com/dashboard&site=myapp&session=0 ``` -------------------------------- ### Zap Logger Adapter Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/api-reference/logger.md Adapt the Zap logging library for use with the custom logger interface. This example shows how to map log messages to Zap's logging levels. ```go import "go.uber.org/zap" type ZapAdapter struct { log *zap.Logger } func (l *ZapAdapter) Logf(format string, args ...interface{}) { msg := fmt.Sprintf(format, args...) switch { case strings.Contains(msg, "[DEBUG]"): l.log.Debug(msg) case strings.Contains(msg, "[INFO]"): l.log.Info(msg) case strings.Contains(msg, "[WARN]"): l.log.Warn(msg) case strings.Contains(msg, "[ERROR]"): l.log.Error(msg) default: l.log.Info(msg) } } opts := auth.Opts{ Logger: &ZapAdapter{log: zap.Must(zap.NewProduction())}, } ``` -------------------------------- ### Telegram Get Auth Token Response Example Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/endpoints.md Response from the Telegram login endpoint, providing a bot identifier and a unique token for user authentication. ```json { "bot": "my_awesome_bot", "token": "abc123xyz" } ``` -------------------------------- ### Initialize Avatar Service and Access Proxy Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/api-reference/avatar.md Demonstrates how to initialize the authentication service with avatar options and access the avatar proxy. ```go // During service initialization opts := auth.Opts{ AvatarStore: avatar.NewLocalFS("/tmp/avatars"), AvatarRoutePath: "/api/v1/avatars", AvatarResizeLimit: 200, } service := auth.NewService(opts) // Access proxy proxy := service.AvatarProxy() ``` -------------------------------- ### Telegram Check Auth Confirmation Response Example Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/endpoints.md Example JSON response upon successful confirmation of Telegram authentication. Includes user details. ```json { "user": { "name": "tg_username", "id": "telegram_", "picture": "https://example.com/avatar/xxx.image" } } ``` -------------------------------- ### Initialize Email Sender Client Source: https://github.com/go-pkgz/auth/blob/master/README.md Configure and initialize the email client for sending notifications. Ensure all email parameters are correctly set. ```go sndr := sender.NewEmailClient(sender.EmailParams{ Host: "email.hostname", Port: 567, SMTPUserName: "username", SMTPPassword: "pass", StartTLS: true, InsecureSkipVerify: false, From: "notify@email.hostname", Subject: "subject", ContentType: "text/html", Charset: "UTF-8", }, log.Default()) authenticator.AddVerifProvider("email", "template goes here", sndr) ``` -------------------------------- ### Direct Authentication GET Request Source: https://github.com/go-pkgz/auth/blob/master/README.md Handles direct authentication via GET request with credentials in query parameters. Note that query strings are not secure for sensitive information. ```http GET /auth//login?user=&passwd=&aud=&session=[1|0] ``` -------------------------------- ### Initialize Authentication Service Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/api-reference/service.md Creates a new Service instance with specified options, including secret reader, URL, and avatar store. ```go import ( "github.com/go-pkgz/auth" "github.com/go-pkgz/auth/avatar" "github.com/go-pkgz/auth/token" ) opts := auth.Opts{ SecretReader: token.SecretFunc(func(aud string) (string, error) { return "my-secret-key", nil }), URL: "https://example.com", AvatarStore: avatar.NewLocalFS("/tmp/avatars"), } service := auth.NewService(opts) ``` -------------------------------- ### Initialize Telegram Provider Source: https://github.com/go-pkgz/auth/blob/master/README.md Set up the Telegram authentication provider with necessary parameters. Obtain the TELEGRAM_TOKEN from BotFather. ```go token := os.Getenv("TELEGRAM_TOKEN") telegram := provider.TelegramHandler{ ProviderName: "telegram", ErrorMsg: "❌ Invalid auth request. Please try clicking link again.", SuccessMsg: "✅ You have successfully authenticated!", Telegram: provider.NewTelegramAPI(token, http.DefaultClient), L: log.Default(), TokenService: service.TokenService(), AvatarSaver: service.AvatarProxy(), } ``` -------------------------------- ### Get Avatar Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/endpoints.md Fetches an avatar image using its ID. ```APIDOC ## GET /avatar/ ### Description Fetches an avatar image using its ID. ### Method GET ### Endpoint /avatar/ ### Parameters #### Path Parameters - **avatar_id** (string) - Required - Avatar ID (format: `.image`) ### Response #### Success Response (200) Image data (Content-Type: image/png or image/jpeg) #### Error Response (404) Not found. ### Request Example ``` GET /avatar/abc123def456abc123def456abc123def456abc1.image ``` ``` -------------------------------- ### Logout Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/endpoints.md Logs out the current user via HTTP GET. ```http GET /auth//logout ``` -------------------------------- ### Get Login Status Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/endpoints.md Checks the current login status of the user. ```APIDOC ## GET /auth/status ### Description Checks the current login status of the user. ### Method GET ### Endpoint /auth/status ### Response #### Success Response (200) JSON object indicating login status and user if logged in. ### Response Example ```json { "status": "logged in", "user": "John Doe" } ``` ```json { "status": "not logged in" } ``` ``` -------------------------------- ### NewGridFS Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/api-reference/avatar.md Creates a new GridFS store for MongoDB, suitable for distributed setups. ```APIDOC ## NewGridFS MongoDB GridFS storage for distributed setups. ### Function Signature ```go func NewGridFS(client *mongo.Client, db, bucket string, timeout time.Duration) Store ``` ### Parameters - **client** (*mongo.Client) - Required - The MongoDB client instance. - **db** (string) - Required - The name of the database to use. - **bucket** (string) - Required - The name of the GridFS bucket. - **timeout** (time.Duration) - Required - The timeout for GridFS operations. ### Returns - **Store**: An initialized GridFS avatar store. ### Example ```go ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017")) if err != nil { log.Fatal(err) } store := avatar.NewGridFS(client, "mydb", "avatars", 5*time.Second) ``` ``` -------------------------------- ### Recommended Go-Pkgz/Auth v2 Import Paths Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/00-START-HERE.md Lists the essential import paths for using version 2 of the go-pkgz/auth library and its related packages. ```go import "github.com/go-pkgz/auth/v2" import "github.com/go-pkgz/auth/v2/token" import "github.com/go-pkgz/auth/v2/middleware" import "github.com/go-pkgz/auth/v2/provider" import "github.com/go-pkgz/auth/v2/avatar" import "github.com/go-pkgz/auth/v2/logger" ``` -------------------------------- ### Verification Request Response (JSON) Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/endpoints.md Example JSON response after a verification request is sent. ```json { "status": "confirmation sent", "address": "user@example.com" } ``` -------------------------------- ### Get Current User Info Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/endpoints.md Fetches the current authenticated user's information. ```APIDOC ## GET /auth/user ### Description Fetches the current authenticated user's information. ### Method GET ### Endpoint /auth/user ### Response #### Success Response (200) JSON object with user details. #### Error Response (401) JSON error object if not authenticated. ### Response Example ```json { "name": "John Doe", "id": "github_abc123", "picture": "https://example.com/avatar/xxx.image", "aud": "myapp", "email": "john@example.com", "attrs": { "admin": true, "role": "editor" } } ``` ``` -------------------------------- ### NewService Constructor Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/api-reference/service.md Initializes and returns a new authentication Service with the provided configuration options. ```APIDOC ## NewService ### Description Initializes and returns a new authentication Service with the provided configuration options. ### Signature ```go func NewService(opts Opts) (res *Service) ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters Table | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | opts | `Opts` | yes | — | Complete set of configuration parameters for the service | ### Returns `*Service` - Configured authentication service ### Throws None (validation happens during provider registration) ### Example ```go import ( "github.com/go-pkgz/auth" "github.com/go-pkgz/auth/avatar" "github.com/go-pkgz/auth/token" ) opts := auth.Opts{ SecretReader: token.SecretFunc(func(aud string) (string, error) { return "my-secret-key", nil }), URL: "https://example.com", AvatarStore: avatar.NewLocalFS("/tmp/avatars"), } service := auth.NewService(opts) ``` ``` -------------------------------- ### Example JSON Error: Invalid Token Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/endpoints.md Illustrates an error response when an authentication token is invalid. ```json { "error": "can't get token: invalid token", "code": "unauthorized" } ``` -------------------------------- ### Token Service: Get Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/api-reference/token-service.md Retrieves and validates token from request (cookie, header, or query parameter). ```APIDOC ## Token Service: Get ### Description Retrieves and validates token from request (cookie, header, or query parameter). ### Method ```go func (j *Service) Get(r *http.Request) (claims Claims, token string, err error) ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **r** (*http.Request) - Required - Incoming HTTP request ### Response #### Success Response - **Claims** - Parsed token claims - **string** - Raw token string - **error** - If no valid token found or validation fails ### Extraction Order 1. Cookie (name from `JWTCookieName`) 2. Header (name from `JWTHeaderKey`) 3. Query parameter (name from `JWTQuery`) ### Request Example ```go claims, tokenStr, err := svc.Get(r) if err != nil { http.Error(w, "Unauthorized", http.StatusUnauthorized) return } fmt.Println(claims.User.Name) ``` ``` -------------------------------- ### Import Main Package (v1) Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/README.md Import necessary packages for the main version (v1) of the auth library. ```go import "github.com/go-pkgz/auth" import "github.com/go-pkgz/auth/token" import "github.com/go-pkgz/auth/middleware" import "github.com/go-pkgz/auth/provider" import "github.com/go-pkgz/auth/avatar" import "github.com/go-pkgz/auth/logger" ``` -------------------------------- ### Setting up a Custom OAuth2 Server Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/api-reference/providers.md This section describes how to set up and run a custom local OAuth2 server for development or custom flows using `CustomServer` and `CustomServerOpt`. ```APIDOC ## Custom OAuth2 Server Embedded local OAuth2 server for development or custom flows. ### CustomServer ```go type CustomServer struct { // unexported } type CustomServerOpt struct { URL string WithLoginPage bool LoginPageHandler LoginPageHandlerFunc L logger.L } func NewCustomServer(srv *oauth2.Server, opts CustomServerOpt) *CustomServer ``` **Example:** ```go sopts := provider.CustomServerOpt{ URL: "http://127.0.0.1:9096", WithLoginPage: true, } customSrv := provider.NewCustomServer(oauth2Server, sopts) go func() { if err := customSrv.Run(context.Background()); err != nil { log.Fatal(err) } }() service.AddCustomProvider("custom", auth.Client{Cid: "cid", Csecret: "secret"}, customSrv.HandlerOpt) ``` ``` -------------------------------- ### Add Verification Provider Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/api-reference/providers.md Example of adding an email verification provider with a custom message template and sender. ```go msgTemplate := ` Hello {{.User}}, Click here to confirm: {{.Token}} Site: {{.Site}} ` service.AddVerifProvider("email", msgTemplate, emailSender) ``` -------------------------------- ### Initialize Auth Service Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/README.md Initializes the Auth service with custom options like a secret reader, URL, and avatar store. Then, adds a new authentication provider. ```go opts := auth.Opts{ SecretReader: token.SecretFunc(func(aud string) (string, error) { return "secret", nil }), URL: "https://example.com", AvatarStore: avatar.NewLocalFS("/tmp/avatars"), } service := auth.NewService(opts) service.AddProvider("github", "cid", "csecret") ``` -------------------------------- ### Redeem Token Response (JSON) Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/endpoints.md Example JSON response upon successful redemption of a verification token. ```json { "user": { "name": "user", "id": "email_", "picture": "https://gravatar.com/avatar/xxx" // if UseGravatar enabled } } ``` -------------------------------- ### Retrieving a Specific Provider Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/api-reference/service.md Get a registered authentication provider by its name. An error is returned if the provider is not found. ```go p, err := service.Provider("github") if err != nil { log.Fatal(err) } ``` -------------------------------- ### Run Root Module Tests Source: https://github.com/go-pkgz/auth/blob/master/AGENTS.md Execute tests for the main go-pkgz/auth module. Use -p 1 to reduce port-collision risk during package test runs. ```bash go test -p 1 ./... ``` -------------------------------- ### AddDevProvider Method Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/api-reference/service.md Registers a development-only OAuth2 provider for testing without real external OAuth2 setup. ```APIDOC ## AddDevProvider ### Description Registers a development-only OAuth2 provider for testing without real external OAuth2 setup. ### Signature ```go func (s *Service) AddDevProvider(host string, port int) ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters Table | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | host | `string` | no | `"127.0.0.1"` | Bind address for dev server (e.g., `"0.0.0.0"` for LAN access) | | port | `int` | no | `8084` | Port for dev OAuth2 server | ### Returns None ### Example ```go service.AddDevProvider("127.0.0.1", 8084) // For dev server accessible from other machines service.AddDevProvider("0.0.0.0", 8084) ``` ``` -------------------------------- ### Add Dev Provider Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/configuration.md Configure a development provider for local testing. Defaults to host '127.0.0.1' and port 8084. ```go service.AddDevProvider(host, port) ``` -------------------------------- ### Logout Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/endpoints.md Logs the user out by clearing authentication cookies. Supports both GET and POST methods for initiating the logout process. ```APIDOC ## (GET|POST) /auth//logout ### Description Logs the user out by clearing authentication-related cookies. ### Method GET, POST ### Endpoint /auth//logout ### Response HTTP 302 redirect or HTTP 200 with JSON status. ### Cookies Cleared - `JWT` - `XSRF-TOKEN` ``` -------------------------------- ### User Attribute Management Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/api-reference/token-service.md Methods for setting and getting custom boolean, string, and string slice attributes for a user. ```APIDOC ## User Methods ### SetBoolAttr / BoolAttr Set/get boolean custom attributes. ```go func (u *User) SetBoolAttr(key string, val bool) func (u *User) BoolAttr(key string) bool ``` ### SetStrAttr / StrAttr Set/get string custom attributes. ```go func (u *User) SetStrAttr(key, val string) func (u *User) StrAttr(key string) string ``` ### SetSliceAttr / SliceAttr Set/get string slice custom attributes. ```go func (u *User) SetSliceAttr(key string, val []string) func (u *User) SliceAttr(key string) []string ``` ``` -------------------------------- ### Set and Get String Attributes Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/api-reference/token-service.md Use SetStrAttr to set a string custom attribute and StrAttr to retrieve it for a user. ```go func (u *User) SetStrAttr(key, val string) func (u *User) StrAttr(key string) string ``` -------------------------------- ### Set and Get Boolean Attributes Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/api-reference/token-service.md Use SetBoolAttr to set a boolean custom attribute and BoolAttr to retrieve it for a user. ```go func (u *User) SetBoolAttr(key string, val bool) func (u *User) BoolAttr(key string) bool ``` -------------------------------- ### Configure Apple Auth Provider Parameters Source: https://github.com/go-pkgz/auth/blob/master/README.md Set up the AppleConfig struct with required credentials obtained from your Apple Developer account. Ensure environment variables are set for TeamID, ClientID, and KeyID. ```go // 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 } ``` -------------------------------- ### Implementing CredChecker with a Function Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/api-reference/providers.md An example of creating a CredChecker using a function literal, suitable for direct integration with verification logic. ```go // Adapter for functions type CredCheckerFunc func(user, password string) (ok bool, err error) checker := provider.CredCheckerFunc(func(user, passwd string) (bool, error) { // Verify against database, LDAP, etc. return db.VerifyPassword(user, passwd) }) service.AddDirectProvider("local", checker) ``` -------------------------------- ### Get Login Status Source: https://github.com/go-pkgz/auth/blob/master/_autodocs/endpoints.md Check the current login status. The response indicates whether the user is logged in and their name, or if they are not logged in. ```http GET /auth/status ``` ```json { "status": "logged in", "user": "John Doe" } ``` ```json { "status": "not logged in" } ```