auth

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: May 17, 2026 License: MIT Imports: 17 Imported by: 4

README

auth — Firebase authentication client

import "github.com/downsized-devs/sdk-go/auth"

Stability: Stable — see STABILITY.md

Firebase Auth wrapper providing token verification, refresh-token exchange, user CRUD, and password sign-in. The HTTP exchange for refresh tokens goes through Google's Identity Toolkit endpoint.

Features

  • Token verification via Firebase Admin SDK
  • Password sign-in & verification
  • Refresh-token exchange and revocation
  • User CRUD: register, get (single + batch), update, delete
  • Context helpers: SetUserAuthInfo, GetUserAuthInfo

Installation

go get github.com/downsized-devs/sdk-go/auth

You'll need a Firebase service-account key file (JSON) and a Firebase Web API key.

Quick Start

import (
    "context"
    "net/http"

    "github.com/downsized-devs/sdk-go/auth"
    "github.com/downsized-devs/sdk-go/logger"
    "github.com/downsized-devs/sdk-go/parser"
)

log := logger.Init(logger.Config{Level: "info"})
json := parser.InitParser(log, parser.Options{}).JSONParser()

a := auth.Init(auth.Config{
    Firebase: auth.FirebaseConf{
        ApiKey:     "<FIREBASE_WEB_API_KEY>",
        AccountKey: auth.FirebaseAccountKey{ /* ... */ },
    },
}, log, json, http.DefaultClient)

tok, err := a.VerifyToken(context.Background(), "Bearer eyJhbGciOi...")

API Reference

Construction
func Init(cfg Config, log logger.Interface, json parser.JsonInterface, httpClient *http.Client) Interface
Interface
Method Signature
VerifyToken (ctx, bearer string) (*firebase_auth.Token, error)
SignInWithPassword (ctx, UserLogin) (UserLoginResponse, error)
VerifyPassword (ctx, email, password string) (bool, error)
RefreshToken (ctx, refreshToken string) (RefreshTokenResponse, error)
RevokeUserRefreshToken (ctx, uid string) error
GetUser (ctx, FirebaseUserParam) ([]FirebaseUser, error)
GetUsers (ctx, []FirebaseUserParam) ([]FirebaseUser, error)
RegisterUser (ctx, FirebaseUser) (FirebaseUser, error)
UpdateUser (ctx, FirebaseUser) (FirebaseUser, error)
DeleteUser (ctx, uid string) error
SetUserAuthInfo (ctx, UserAuthParam) context.Context
GetUserAuthInfo (ctx) (UserAuthInfo, error)

Key types live in auth/entity.go: FirebaseUser, UserLogin, UserLoginResponse, RefreshTokenRequest/Response, UserAuthInfo, UserAuthParam.

Configuration

Field Required Description
Firebase.ApiKey yes Firebase Web API key (used at the Identity Toolkit refresh endpoint).
Firebase.AccountKey yes Service-account credentials.

Load credentials from a secrets manager — never hard-code.

Examples

Gin middleware that verifies Authorization
func AuthMiddleware(a auth.Interface) gin.HandlerFunc {
    return func(c *gin.Context) {
        tok, err := a.VerifyToken(c.Request.Context(), c.GetHeader("Authorization"))
        if err != nil {
            c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": err.Error()})
            return
        }
        ctx := a.SetUserAuthInfo(c.Request.Context(), auth.UserAuthParam{UID: tok.UID})
        c.Request = c.Request.WithContext(ctx)
        c.Next()
    }
}
Rotate a leaked refresh token
if err := a.RevokeUserRefreshToken(ctx, uid); err != nil {
    return errors.WrapWithCode(err, codes.CodeFirebaseRevokeToken, "rotate session")
}

Error Handling

Errors are wrapped with codes auth-range codes (1700–1799). Dispatch with errors.GetCode(err).

Dependencies

  • Internal: codes, errors, logger, null, parser
  • External: firebase.google.com/go, firebase.google.com/go/auth, google.golang.org/api/identitytoolkit/v1, google.golang.org/api/identitytoolkit/v3, google.golang.org/api/option

Testing

go test ./auth/...

Uses fixture-based mocks — no live Firebase needed.

Contributing

See CONTRIBUTING.md. Changing Interface is breaking — coordinate with downstream consumers first.

  • security — for password hashing if you keep your own user store.
  • ratelimiter — pair with auth to rate-limit token verification.
  • appcontext — for request/user metadata that flows alongside auth state.

Documentation

Index

Constants

View Source
const (
	ContentType             = "Content-Type"
	ApplicationJson         = "application/json"
	ExchangeRefreshTokenURL = "https://securetoken.googleapis.com/v1/token" //nolint: gosec
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	SkipFirebaseInit bool
	Firebase         FirebaseConf
}

type FirebaseAccountKey

type FirebaseAccountKey struct {
	Type                    string `json:"type"`
	ProjectID               string `json:"project_id"`
	PrivateKeyID            string `json:"private_key_id"`
	PrivateKey              string `json:"private_key"`
	ClientEmail             string `json:"client_email"`
	ClientID                string `json:"client_id"`
	AuthURI                 string `json:"auth_uri"`
	TokenURI                string `json:"token_uri"`
	AuthProviderx509CertURL string `json:"auth_provider_x509_cert_url"`
	Clientx509CertURL       string `json:"client_x509_cert_url"`
}

type FirebaseConf

type FirebaseConf struct {
	AccountKey FirebaseAccountKey
	ApiKey     string
}

type FirebaseUser

type FirebaseUser struct {
	ID                 string    `json:"id"`
	Email              string    `json:"email"`
	IsEmailVerified    null.Bool `json:"is_email_verified"`
	PhoneNumber        string    `json:"phone_number"`
	Password           string    `json:"password"`
	DisplayName        string    `json:"display_name"`
	PhotoURL           string    `json:"photo_url"`
	IsDisabled         null.Bool `json:"is_disabled"`
	CreationTimestamp  int64     `json:"creation_timestamp"`
	LastLoginTimestamp int64     `json:"last_login_timestamp"`
}

type FirebaseUserParam

type FirebaseUserParam struct {
	ID          string `json:"id"`
	Email       string `json:"email"`
	PhoneNumber string `json:"phone_number"`
}

type Interface

type Interface interface {
	VerifyToken(ctx context.Context, bearertoken string) (*firebase_auth.Token, error)
	GetUser(ctx context.Context, userParam FirebaseUserParam) ([]FirebaseUser, error)
	RegisterUser(ctx context.Context, user FirebaseUser) (FirebaseUser, error)
	UpdateUser(ctx context.Context, user FirebaseUser) (FirebaseUser, error)
	DeleteUser(ctx context.Context, userID string) error
	SetUserAuthInfo(ctx context.Context, param UserAuthParam) context.Context
	GetUserAuthInfo(ctx context.Context) (UserAuthInfo, error)
	RevokeUserRefreshToken(ctx context.Context, uid string) error
	VerifyPassword(ctx context.Context, email, password string) (bool, error)
	GetUsers(ctx context.Context, userParams []FirebaseUserParam) ([]FirebaseUser, error)
	SignInWithPassword(ctx context.Context, param UserLogin) (UserLoginResponse, error)
	RefreshToken(ctx context.Context, refreshToken string) (RefreshTokenResponse, error)
}

func Init

func Init(cfg Config, log logger.Interface, json parser.JsonInterface, httpClient *http.Client) Interface

type RefreshTokenRequest

type RefreshTokenRequest struct {
	GrantType    string `json:"grant_type"`
	RefreshToken string `json:"refresh_token"`
}

type RefreshTokenResponse

type RefreshTokenResponse struct {
	ExpiresIn    string `json:"expires_in"`
	TokenType    string `json:"token_type"`
	RefreshToken string `json:"refresh_token"`
	IDToken      string `json:"id_token"`
	UserID       string `json:"user_id"`
	ProjectID    string `json:"project_id"`
}

type Token

type Token struct {
	TokenType    string `json:"token_type"`
	AccessToken  string `json:"access_token"`
	RefreshToken string `json:"refresh_token"`
	ExpiresIn    int    `json:"expires_in"`
}

type User

type User struct {
	ID          int64  `db:"id" json:"id"`
	CompanyID   int64  `db:"fk_company_id" json:"companyId"`
	Name        string `db:"name" json:"name"`
	Email       string `db:"email" json:"email"`
	UID         string `db:"uid" json:"uid"`
	RoleID      int64  `db:"fk_role_id" json:"roleId"`
	RoleRank    int64  `db:"rank" json:"roleRank"`
	PhoneNumber string `db:"phone_num" json:"phoneNumber"`
	IsQA        bool   `db:"is_qa" json:"isQa"`
}

type UserAuthInfo

type UserAuthInfo struct {
	User           User                `json:"user"`
	FirebaseToken  firebase_auth.Token `json:"firebaseToken"`
	UserCredential UserCredential      `json:"userCredential"`
}

type UserAuthParam

type UserAuthParam struct {
	User           User                 `json:"user"`
	FirebaseToken  *firebase_auth.Token `json:"firebaseToken"`
	UserCredential *UserCredential      `json:"userCredential"`
}

type UserCredential

type UserCredential struct {
	ID           int64     `db:"id" json:"id"`
	UserID       int64     `db:"fk_user_id" json:"userId"`
	ServiceID    int64     `db:"fk_service_id" json:"serviceId"`
	AccessToken  string    `db:"access_token" json:"accessToken"`
	RefreshToken string    `db:"refresh_token" json:"refreshToken"`
	UserAgent    string    `db:"user_agent" json:"userAgent"`
	ExpiredAt    null.Time `db:"expired_at" json:"expiredAt"`
	IsRevoke     bool      `db:"is_revoke" json:"isRevoke"`
}

type UserLogin

type UserLogin struct {
	Email    string `json:"email"`
	Password string `json:"password"`
}

type UserLoginResponse

type UserLoginResponse struct {
	Kind           string `json:"kind"`
	LocalID        string `json:"localId"`
	Email          string `json:"email"`
	DisplayName    string `json:"displayName"`
	IDToken        string `json:"idToken"`
	Registered     bool   `json:"registered"`
	ProfilePicture string `json:"profilePicture"`
	RefreshToken   string `json:"refreshToken"`
	ExpiresIn      int64  `json:"expiresIn"`
}

type UserRefreshTokenParam

type UserRefreshTokenParam struct {
	RefreshToken string `form:"refreshToken"`
}

Jump to

Keyboard shortcuts

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