mirror of
https://github.com/foomo/gotsrpc.git
synced 2026-04-16 18:54:26 +00:00
This example showcases gotsrpc's special Context function for centralized authentication. The Context function handles all authentication logic, keeping service methods clean and focused on business logic. Key principle: Centralized authentication via Context function - Context function validates Authorization header once - Service methods remain clean without auth boilerplate - Single point of authentication for entire service Example includes: - AuthService: Login/logout operations - HelloService: Demonstrates Context function pattern - Complete build system with Makefile - TypeScript client with proper ES6 modules - Comprehensive tests and documentation Files: example/auth/ (complete authentication example)
gotsrpc Authentication Example
This example demonstrates how to implement client authentication using gotsrpc's special Context function handling. It shows a complete authentication flow with two services:
- Authentication Service - Handles login/logout operations
- Hello Service - Requires authentication and provides personalized responses
Architecture
Authentication Flow
- Client logs in with username/password
- Server validates credentials and returns a JWT-like token
- Client stores token and includes it in Authorization header for subsequent requests
- Hello service's
Contextmethod validates the token before processing requests - Authenticated user information is available to other service methods
Key Features
- Centralized Authentication: The
Contextfunction handles auth for all Hello service methods - Token-based Security: Uses secure random tokens for session management
- User Context: Authenticated user information is available throughout the request
- Clean Separation: Authentication logic is separate from business logic
Services
AuthService
Login(username, password)- Authenticates user and returns tokenLogout(token)- Invalidates a tokenValidateToken(token)- Validates token and returns user info
HelloService
Context(w, r)- Special function that handles authentication via Authorization headerSayHello(message)- Returns personalized greeting (requires authentication)GetUserInfo()- Returns current user information (requires authentication)
How the Context Function Works
The Context function is specially handled by gotsrpc:
- Detection: gotsrpc automatically detects functions with
http.ResponseWriterand*http.Requestparameters - Special Generation: The generated code calls
Contextfirst, then other methods - Authentication:
Contextvalidates the Authorization header and sets up user context - Error Handling: If authentication fails,
Contextwrites an error response and returns early - Success: If authentication succeeds, other methods can access the authenticated user
Running the Example
Prerequisites
- Go 1.19+
- Node.js (for TypeScript compilation)
gotsrpctool installed
Quick Start
cd example/auth
make dev
This will:
- Clean generated files
- Generate gotsrpc server and client code
- Compile TypeScript to JavaScript
- Start the server on
http://localhost:8080
Manual Steps
If you prefer to run steps manually:
# Generate gotsrpc code
make generate
# Compile TypeScript client
make build-client
# Start the server
make run-server
Available Makefile Commands
make generate- Generate gotsrpc server and client codemake build-client- Compile TypeScript to JavaScriptmake run-server- Start the Go servermake run- Build client and run servermake dev- Full workflow: generate + build + runmake clean- Remove compiled JavaScript files
Access the Client
Open http://localhost:8080 in your browser to access the web interface.
Test Accounts
- Username:
alice, Password:password123 - Username:
bob, Password:secret456 - Username:
admin, Password:admin789
API Endpoints
Authentication
POST /auth/Login- Login with username/passwordPOST /auth/Logout- Logout with tokenPOST /auth/ValidateToken- Validate token and get user info
Hello Service (Requires Authentication)
POST /hello/Context- Authentication context (special gotsrpc function)POST /hello/SayHello- Say hello with personalized messagePOST /hello/GetUserInfo- Get current user information
Code Structure
example/auth/
├── service/
│ ├── auth.go # Authentication service implementation
│ ├── hello.go # Hello service with Context authentication
│ ├── gotsrpc_gen.go # Generated gotsrpc server code
│ └── gotsrpcclient_gen.go # Generated gotsrpc client code
├── client/
│ ├── index.html # Web interface
│ ├── src/
│ │ ├── app.ts # TypeScript client code
│ │ ├── client_gen.ts # Generated gotsrpc client
│ │ ├── vo_gen.ts # Generated value objects
│ │ ├── vo-time_gen.ts # Generated time value objects
│ │ └── types.d.ts # TypeScript type definitions
│ ├── dist/
│ │ ├── app.js # Compiled JavaScript
│ │ ├── client_gen.js # Compiled generated client
│ │ ├── vo_gen.js # Compiled value objects
│ │ └── vo-time_gen.js # Compiled time objects
│ └── tsconfig.json # TypeScript configuration
├── main.go # Server setup and HTTP handlers
├── main_test.go # Tests for gotsrpc Context function
├── gotsrpc.yml # gotsrpc configuration
├── Makefile # Build automation
└── README.md # This file
Key Implementation Details
Authentication in Context Function
func (h *HelloHandler) Context(w http.ResponseWriter, r *http.Request) {
// Extract and validate Authorization header
authHeader := r.Header.Get("Authorization")
if !strings.HasPrefix(authHeader, "Bearer ") {
http.Error(w, "Invalid authorization format", http.StatusUnauthorized)
return
}
// Validate token and store user context
token := strings.TrimPrefix(authHeader, "Bearer ")
user, err := h.authService.ValidateToken(token)
if err != nil {
http.Error(w, "Invalid token", http.StatusUnauthorized)
return
}
// Store user for other methods to use
h.currentUser = &user
}
Client-Side Token Management
// Include token in requests
if (requiresAuth && authToken) {
options.headers = {
...options.headers,
'Authorization': `Bearer ${authToken}`,
};
}
Generated Code Usage
The example uses generated gotsrpc code for both server and client:
Server-side (Go):
// Generated gotsrpc proxies handle HTTP routing and method calls
authProxy := service.NewDefaultAuthServiceGoTSRPCProxy(authHandler)
helloProxy := service.NewDefaultHelloServiceGoTSRPCProxy(helloHandler)
// Register with HTTP mux
mux.Handle("/auth/", authProxy)
mux.Handle("/hello/", helloProxy)
Client-side (TypeScript):
// Import generated clients and types
import { AuthServiceClient, HelloServiceClient } from './client_gen.js';
import * as types from './vo_gen.js';
// Use generated clients
const authClient = new AuthServiceClient(transport);
const helloClient = new HelloServiceClient(transport);
Benefits of This Pattern
- Single Point of Authentication: All auth logic is centralized in the
Contextfunction - No Code Duplication: Other service methods don't need to implement authentication
- Flexible: Can implement any authentication scheme (JWT, API keys, OAuth, etc.)
- Clean Separation: Business logic is separate from authentication concerns
- Type Safety: Full TypeScript support for client-side code
- Code Generation: gotsrpc generates both server and client code automatically
- Build Automation: Makefile provides clean build and development workflow
Production Considerations
For production use, consider:
- Token Storage: Use Redis or database instead of in-memory storage
- Password Hashing: Use bcrypt or similar for password storage
- Token Expiration: Implement token expiration and refresh mechanisms
- HTTPS: Always use HTTPS in production
- Rate Limiting: Implement rate limiting for authentication endpoints
- Logging: Add comprehensive logging for security events