đš Go Code Examples
package main
import (
"bytes"
"crypto/md5"
"encoding/json"
"fmt"
"io"
"net"
"net/http"
"os"
"runtime"
"time"
)
const (
APIKey = "your-api-key-here"
APIURL = "http://your-domain.com/api/license/auth"
Product = "MyGoApp"
Version = "1.0.0"
)
type AuthRequest struct {
Data AuthData `json:"data"`
}
type AuthData struct {
Product string `json:"product"`
Version string `json:"version"`
LicenseKey string `json:"licensekey"`
IP string `json:"ip"`
HWID string `json:"hwid"`
}
type AuthResponse struct {
StatusOverview string `json:"status_overview"`
StatusMsg string `json:"status_msg"`
DiscordUsername string `json:"discord_username"`
DiscordTag string `json:"discord_tag"`
DiscordID string `json:"discord_id"`
ExpireDate string `json:"expire_date"`
StaffLicense bool `json:"staff_license"`
Version string `json:"version"`
Message string `json:"message"`
}
type TKIAuth struct {
client *http.Client
}
func NewTKIAuth() *TKIAuth {
return &TKIAuth{
client: &http.Client{
Timeout: 30 * time.Second,
},
}
}
func (t *TKIAuth) getHWID() string {
// Generate HWID based on system info
hostname, _ := os.Hostname()
arch := runtime.GOARCH
os := runtime.GOOS
hwString := fmt.Sprintf("%s-%s-%s", hostname, arch, os)
hash := md5.Sum([]byte(hwString))
return fmt.Sprintf("GO-%x", hash)[:18]
}
func (t *TKIAuth) getLocalIP() string {
// Get local IP address
conn, err := net.Dial("udp", "8.8.8.8:80")
if err != nil {
return "127.0.0.1"
}
defer conn.Close()
localAddr := conn.LocalAddr().(*net.UDPAddr)
return localAddr.IP.String()
}
func (t *TKIAuth) Authenticate(licenseKey string) (*AuthResponse, error) {
// Prepare request
authReq := AuthRequest{
Data: AuthData{
Product: Product,
Version: Version,
LicenseKey: licenseKey,
IP: t.getLocalIP(),
HWID: t.getHWID(),
},
}
jsonData, err := json.Marshal(authReq)
if err != nil {
return nil, fmt.Errorf("failed to marshal request: %w", err)
}
// Create HTTP request
req, err := http.NewRequest("POST", APIURL, bytes.NewBuffer(jsonData))
if err != nil {
return nil, fmt.Errorf("failed to create request: %w", err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", APIKey)
req.Header.Set("User-Agent", "TKI-Auth-Go/1.0")
// Send request
resp, err := t.client.Do(req)
if err != nil {
return nil, fmt.Errorf("request failed: %w", err)
}
defer resp.Body.Close()
// Read response
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("failed to read response: %w", err)
}
var authResp AuthResponse
if err := json.Unmarshal(body, &authResp); err != nil {
return nil, fmt.Errorf("failed to parse response: %w", err)
}
// Check response
if resp.StatusCode == 200 && authResp.StatusOverview == "success" {
return &authResp, nil
}
return nil, fmt.Errorf("authentication failed: %s (HTTP %d)",
authResp.Message, resp.StatusCode)
}
func (t *TKIAuth) AuthenticateWithRetry(licenseKey string, maxRetries int) (*AuthResponse, error) {
var lastErr error
for attempt := 1; attempt <= maxRetries; attempt++ {
resp, err := t.Authenticate(licenseKey)
if err == nil {
return resp, nil
}
lastErr = err
if attempt < maxRetries {
waitTime := time.Duration(attempt) * time.Second
fmt.Printf("Attempt %d failed, retrying in %v...\n", attempt, waitTime)
time.Sleep(waitTime)
}
}
return nil, fmt.Errorf("authentication failed after %d attempts: %w", maxRetries, lastErr)
}
func main() {
fmt.Print("Enter license key: ")
var licenseKey string
fmt.Scanln(&licenseKey)
auth := NewTKIAuth()
fmt.Println("Authenticating license...")
resp, err := auth.AuthenticateWithRetry(licenseKey, 3)
if err != nil {
fmt.Printf("â Authentication failed: %v\n", err)
os.Exit(1)
}
fmt.Println("â License authenticated!")
fmt.Printf(" User: %s\n", resp.DiscordUsername)
fmt.Printf(" Tag: %s\n", resp.DiscordTag)
fmt.Printf(" Expires: %s\n", resp.ExpireDate)
fmt.Printf(" Staff License: %t\n", resp.StaffLicense)
fmt.Printf(" Version: %s\n", resp.Version)
fmt.Println("Starting application...")
// Your application logic here
}
Advanced Go Implementationâ
package main
import (
"context"
"encoding/json"
"fmt"
"log"
"net/http"
"sync"
"time"
)
type LicenseManager struct {
auth *TKIAuth
licenseKey string
licenseInfo *AuthResponse
isAuthenticated bool
mu sync.RWMutex
ctx context.Context
cancel context.CancelFunc
}
func NewLicenseManager() *LicenseManager {
ctx, cancel := context.WithCancel(context.Background())
return &LicenseManager{
auth: NewTKIAuth(),
ctx: ctx,
cancel: cancel,
}
}
func (lm *LicenseManager) Authenticate(licenseKey string) error {
lm.mu.Lock()
defer lm.mu.Unlock()
resp, err := lm.auth.AuthenticateWithRetry(licenseKey, 3)
if err != nil {
return err
}
lm.licenseKey = licenseKey
lm.licenseInfo = resp
lm.isAuthenticated = true
return nil
}
func (lm *LicenseManager) IsAuthenticated() bool {
lm.mu.RLock()
defer lm.mu.RUnlock()
return lm.isAuthenticated
}
func (lm *LicenseManager) GetLicenseInfo() *AuthResponse {
lm.mu.RLock()
defer lm.mu.RUnlock()
if lm.licenseInfo != nil {
info := *lm.licenseInfo
return &info
}
return nil
}
func (lm *LicenseManager) StartPeriodicValidation(interval time.Duration) {
go func() {
ticker := time.NewTicker(interval)
defer ticker.Stop()
for {
select {
case <-lm.ctx.Done():
return
case <-ticker.C:
if lm.IsAuthenticated() {
if err := lm.validateLicense(); err != nil {
log.Printf("Periodic validation failed: %v", err)
lm.onLicenseExpired()
return
}
log.Println("â Periodic validation successful")
}
}
}
}()
}
func (lm *LicenseManager) validateLicense() error {
lm.mu.RLock()
licenseKey := lm.licenseKey
lm.mu.RUnlock()
_, err := lm.auth.Authenticate(licenseKey)
return err
}
func (lm *LicenseManager) onLicenseExpired() {
lm.mu.Lock()
lm.isAuthenticated = false
lm.mu.Unlock()
log.Println("â License expired or validation failed!")
// Implement your logic here
}
func (lm *LicenseManager) Shutdown() {
lm.cancel()
}
// HTTP Server Example
type Server struct {
licenseManager *LicenseManager
mux *http.ServeMux
}
func NewServer() *Server {
s := &Server{
licenseManager: NewLicenseManager(),
mux: http.NewServeMux(),
}
s.setupRoutes()
return s
}
func (s *Server) setupRoutes() {
s.mux.HandleFunc("/", s.requireAuth(s.handleHome))
s.mux.HandleFunc("/login", s.handleLogin)
s.mux.HandleFunc("/authenticate", s.handleAuthenticate)
s.mux.HandleFunc("/logout", s.handleLogout)
}
func (s *Server) requireAuth(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if !s.licenseManager.IsAuthenticated() {
http.Redirect(w, r, "/login", http.StatusFound)
return
}
next(w, r)
}
}
func (s *Server) handleHome(w http.ResponseWriter, r *http.Request) {
info := s.licenseManager.GetLicenseInfo()
if info == nil {
http.Redirect(w, r, "/login", http.StatusFound)
return
}
w.Header().Set("Content-Type", "text/html")
fmt.Fprintf(w, `
<h1>Welcome to Licensed App!</h1>
<p>User: %s</p>
<p>Expires: %s</p>
<p>Staff License: %t</p>
<a href="/logout">Logout</a>
`, info.DiscordUsername, info.ExpireDate, info.StaffLicense)
}
func (s *Server) handleLogin(w http.ResponseWriter, r *http.Request) {
error := r.URL.Query().Get("error")
errorMsg := ""
if error != "" {
errorMsg = fmt.Sprintf(`<p style="color: red;">%s</p>`, error)
}
w.Header().Set("Content-Type", "text/html")
fmt.Fprintf(w, `
<h1>License Authentication</h1>
<form method="post" action="/authenticate">
<input type="text" name="license_key" placeholder="Enter license key" required>
<button type="submit">Authenticate</button>
</form>
%s
`, errorMsg)
}
func (s *Server) handleAuthenticate(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
http.Redirect(w, r, "/login", http.StatusFound)
return
}
licenseKey := r.FormValue("license_key")
if licenseKey == "" {
http.Redirect(w, r, "/login?error=Please+enter+a+license+key", http.StatusFound)
return
}
if err := s.licenseManager.Authenticate(licenseKey); err != nil {
http.Redirect(w, r, "/login?error="+err.Error(), http.StatusFound)
return
}
// Start periodic validation
s.licenseManager.StartPeriodicValidation(30 * time.Minute)
http.Redirect(w, r, "/", http.StatusFound)
}
func (s *Server) handleLogout(w http.ResponseWriter, r *http.Request) {
s.licenseManager.Shutdown()
s.licenseManager = NewLicenseManager()
http.Redirect(w, r, "/login", http.StatusFound)
}
func (s *Server) Start(addr string) error {
log.Printf("Server starting on %s", addr)
return http.ListenAndServe(addr, s.mux)
}
// CLI Application Example
type CLIApp struct {
licenseManager *LicenseManager
}
func NewCLIApp() *CLIApp {
return &CLIApp{
licenseManager: NewLicenseManager(),
}
}
func (app *CLIApp) Run() error {
fmt.Print("Enter license key: ")
var licenseKey string
fmt.Scanln(&licenseKey)
fmt.Println("Authenticating license...")
if err := app.licenseManager.Authenticate(licenseKey); err != nil {
return fmt.Errorf("authentication failed: %w", err)
}
info := app.licenseManager.GetLicenseInfo()
fmt.Println("â License authenticated!")
fmt.Printf(" User: %s\n", info.DiscordUsername)
fmt.Printf(" Expires: %s\n", info.ExpireDate)
fmt.Printf(" Staff License: %t\n", info.StaffLicense)
// Start periodic validation
app.licenseManager.StartPeriodicValidation(30 * time.Minute)
fmt.Println("Starting application...")
// Simulate application running
for app.licenseManager.IsAuthenticated() {
fmt.Println("Application is running...")
time.Sleep(10 * time.Second)
}
fmt.Println("Application stopped due to license issues")
return nil
}
func (app *CLIApp) Shutdown() {
app.licenseManager.Shutdown()
}
// Example usage
func exampleCLI() {
app := NewCLIApp()
defer app.Shutdown()
if err := app.Run(); err != nil {
log.Fatalf("Application error: %v", err)
}
}
func exampleServer() {
server := NewServer()
log.Fatal(server.Start(":8080"))
}
func main() {
// Choose which example to run
if len(os.Args) > 1 && os.Args[1] == "server" {
exampleServer()
} else {
exampleCLI()
}
}
Go Modules (go.mod)â
module tkiauth-example
go 1.21
require (
// No external dependencies needed for basic functionality
)
Build Instructionsâ
# Build the application
go build -o tkiauth-app main.go
# Run CLI version
./tkiauth-app
# Run server version
./tkiauth-app server
# Cross-compile for different platforms
GOOS=windows GOARCH=amd64 go build -o tkiauth-app.exe main.go
GOOS=linux GOARCH=amd64 go build -o tkiauth-app-linux main.go
GOOS=darwin GOARCH=amd64 go build -o tkiauth-app-mac main.go