
Security News
Static vs. Runtime Reachability: Insights from Latio’s On the Record Podcast
The Latio podcast explores how static and runtime reachability help teams prioritize exploitable vulnerabilities and streamline AppSec workflows.
github.com/CrisisTextLine/modular/modules/auth
The Authentication module provides comprehensive authentication capabilities for the Modular framework, including JWT tokens, session management, password hashing, and OAuth2/OIDC integration.
go get github.com/CrisisTextLine/modular/modules/auth
auth:
jwt:
secret: "your-jwt-secret-key"
expiration: "24h"
refresh_expiration: "168h"
issuer: "your-app-name"
password:
min_length: 8
require_upper: true
require_lower: true
require_digit: true
require_special: false
bcrypt_cost: 12
session:
store: "memory"
cookie_name: "session_id"
max_age: "24h"
secure: true
http_only: true
auth:
oauth2:
providers:
google:
client_id: "your-google-client-id"
client_secret: "your-google-client-secret"
redirect_url: "http://localhost:8080/auth/google/callback"
scopes: ["openid", "email", "profile"]
auth_url: "https://accounts.google.com/o/oauth2/auth"
token_url: "https://oauth2.googleapis.com/token"
user_info_url: "https://www.googleapis.com/oauth2/v2/userinfo"
package main
import (
"github.com/CrisisTextLine/modular"
"github.com/CrisisTextLine/modular/modules/auth"
)
func main() {
app := modular.NewApplication()
// Register the auth module
app.RegisterModule(auth.NewModule())
// Start the application
app.Start()
}
// Get the auth service from the application
var authService auth.AuthService
err := app.GetService(auth.ServiceName, &authService)
if err != nil {
log.Fatal(err)
}
// Hash a password
hashedPassword, err := authService.HashPassword("userpassword123")
if err != nil {
log.Fatal(err)
}
// Verify a password
err = authService.VerifyPassword(hashedPassword, "userpassword123")
if err != nil {
log.Println("Invalid password")
}
// Generate JWT tokens
customClaims := map[string]interface{}{
"email": "user@example.com",
"roles": []string{"user", "admin"},
"permissions": []string{"read", "write"},
}
tokenPair, err := authService.GenerateToken("user-123", customClaims)
if err != nil {
log.Fatal(err)
}
// Validate a token
claims, err := authService.ValidateToken(tokenPair.AccessToken)
if err != nil {
log.Println("Invalid token:", err)
return
}
log.Printf("User ID: %s, Email: %s", claims.UserID, claims.Email)
// Create a session
metadata := map[string]interface{}{
"ip_address": "127.0.0.1",
"user_agent": "Mozilla/5.0...",
}
session, err := authService.CreateSession("user-123", metadata)
if err != nil {
log.Fatal(err)
}
// Get a session
retrievedSession, err := authService.GetSession(session.ID)
if err != nil {
log.Println("Session not found:", err)
return
}
// Refresh a session (extend expiration)
refreshedSession, err := authService.RefreshSession(session.ID)
if err != nil {
log.Fatal(err)
}
// Delete a session
err = authService.DeleteSession(session.ID)
if err != nil {
log.Fatal(err)
}
// Get OAuth2 authorization URL
state := "random-state-string"
authURL, err := authService.GetOAuth2AuthURL("google", state)
if err != nil {
log.Fatal(err)
}
// Redirect user to authURL...
// Exchange authorization code for user info
code := "authorization-code-from-callback"
result, err := authService.ExchangeOAuth2Code("google", code, state)
if err != nil {
log.Fatal(err)
}
log.Printf("OAuth2 Result: %+v", result)
You can implement custom storage backends by implementing the UserStore
and SessionStore
interfaces:
type DatabaseUserStore struct {
db *sql.DB
}
func (s *DatabaseUserStore) GetUser(ctx context.Context, userID string) (*auth.User, error) {
// Implement database query
}
func (s *DatabaseUserStore) CreateUser(ctx context.Context, user *auth.User) error {
// Implement database insert
}
// Implement other UserStore methods...
// Register custom stores
app.RegisterService("user_store", &DatabaseUserStore{db: db})
app.RegisterService("session_store", &RedisSessionStore{client: redisClient})
The main authentication service interface provides the following methods:
GenerateToken(userID string, claims map[string]interface{}) (*TokenPair, error)
ValidateToken(token string) (*Claims, error)
RefreshToken(refreshToken string) (*TokenPair, error)
HashPassword(password string) (string, error)
VerifyPassword(hashedPassword, password string) error
ValidatePasswordStrength(password string) error
CreateSession(userID string, metadata map[string]interface{}) (*Session, error)
GetSession(sessionID string) (*Session, error)
DeleteSession(sessionID string) error
RefreshSession(sessionID string) (*Session, error)
GetOAuth2AuthURL(provider, state string) (string, error)
ExchangeOAuth2Code(provider, code, state string) (*OAuth2Result, error)
type User struct {
ID string `json:"id"`
Email string `json:"email"`
PasswordHash string `json:"-"`
Roles []string `json:"roles"`
Permissions []string `json:"permissions"`
Active bool `json:"active"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
LastLoginAt *time.Time `json:"last_login_at,omitempty"`
Metadata map[string]interface{} `json:"metadata,omitempty"`
}
type Session struct {
ID string `json:"id"`
UserID string `json:"user_id"`
CreatedAt time.Time `json:"created_at"`
ExpiresAt time.Time `json:"expires_at"`
IPAddress string `json:"ip_address"`
UserAgent string `json:"user_agent"`
Active bool `json:"active"`
Metadata map[string]interface{} `json:"metadata,omitempty"`
}
type TokenPair struct {
AccessToken string `json:"access_token"`
RefreshToken string `json:"refresh_token"`
TokenType string `json:"token_type"`
ExpiresIn int64 `json:"expires_in"`
ExpiresAt time.Time `json:"expires_at"`
}
The module includes comprehensive tests covering all functionality:
cd modules/auth
go test -v
See the examples/
directory for complete usage examples including:
github.com/golang-jwt/jwt/v5
- JWT token handlinggolang.org/x/crypto
- Password hashinggolang.org/x/oauth2
- OAuth2 client implementationThis module is part of the Modular framework and is licensed under the same terms.
FAQs
Unknown package
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
The Latio podcast explores how static and runtime reachability help teams prioritize exploitable vulnerabilities and streamline AppSec workflows.
Security News
The latest Opengrep releases add Apex scanning, precision rule tuning, and performance gains for open source static code analysis.
Security News
npm now supports Trusted Publishing with OIDC, enabling secure package publishing directly from CI/CD workflows without relying on long-lived tokens.