Skip to main content

🐹 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