All integrations

Go Integration

net/http and popular frameworks

Turalogin integration in Go is lightweight and explicit. Use net/http or any HTTP client library. Start auth to send a magic link email, handle the callback when users click the link, and verify the token. Ideal for APIs, microservices, and high-performance backends.

  • Works with net/http, Gin, Echo, Chi, and other frameworks
  • Magic link flow with customizable callback URL
  • Zero external dependencies for basic integration
  • Fast JWT verification with standard libraries
  • Excellent for microservices architecture

Implementation Examples

1. Environment Configuration

Set up your environment variables for local development and production.

.env
1# Your Turalogin API key from the dashboard
2TURALOGIN_API_KEY=tl_live_xxxxxxxxxxxxx
3
4# The URL where magic links will redirect to
5# Development:
6APP_LOGIN_VALIDATION_URL=http://localhost:8080/auth/callback
7
8# Production (update for your domain):
9# APP_LOGIN_VALIDATION_URL=https://myapp.com/auth/callback

2. Start Authentication

Create an HTTP handler to initiate authentication. This sends a magic link to the user's email.

handlers/auth.go
1package handlers
2
3import (
4 "bytes"
5 "encoding/json"
6 "net/http"
7 "os"
8)
9
10var (
11 turaloginAPIKey = os.Getenv("TURALOGIN_API_KEY")
12 turaloginURL = "https://api.turalogin.com/api/v1"
13 validationURL = os.Getenv("APP_LOGIN_VALIDATION_URL")
14)
15
16type StartAuthRequest struct {
17 Email string `json:"email"`
18}
19
20func StartAuth(w http.ResponseWriter, r *http.Request) {
21 var req StartAuthRequest
22 if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
23 http.Error(w, `{"error": "Invalid request"}`, http.StatusBadRequest)
24 return
25 }
26
27 if req.Email == "" {
28 http.Error(w, `{"error": "Email is required"}`, http.StatusBadRequest)
29 return
30 }
31
32 // Call Turalogin API
33 payload, _ := json.Marshal(map[string]string{
34 "email": req.Email,
35 "validationUrl": validationURL, // Where the magic link redirects to
36 })
37
38 httpReq, _ := http.NewRequest("POST", turaloginURL+"/auth/start", bytes.NewBuffer(payload))
39 httpReq.Header.Set("Authorization", "Bearer "+turaloginAPIKey)
40 httpReq.Header.Set("Content-Type", "application/json")
41
42 client := &http.Client{}
43 resp, err := client.Do(httpReq)
44 if err != nil {
45 http.Error(w, `{"error": "Failed to contact auth service"}`, http.StatusInternalServerError)
46 return
47 }
48 defer resp.Body.Close()
49
50 if resp.StatusCode != http.StatusOK {
51 var errResp map[string]interface{}
52 json.NewDecoder(resp.Body).Decode(&errResp)
53 w.Header().Set("Content-Type", "application/json")
54 w.WriteHeader(resp.StatusCode)
55 json.NewEncoder(w).Encode(errResp)
56 return
57 }
58
59 w.Header().Set("Content-Type", "application/json")
60 json.NewEncoder(w).Encode(map[string]interface{}{
61 "success": true,
62 "message": "Check your email for the login link",
63 })
64}

3. Handle Magic Link Callback

Create a callback handler that receives the token from the magic link and verifies it.

handlers/auth.go
1type User struct {
2 ID string `json:"id"`
3 Email string `json:"email"`
4}
5
6type VerifyAuthResponse struct {
7 Token string `json:"token"`
8 User User `json:"user"`
9}
10
11func AuthCallback(w http.ResponseWriter, r *http.Request) {
12 token := r.URL.Query().Get("token")
13
14 if token == "" {
15 http.Redirect(w, r, "/login?error=invalid_link", http.StatusFound)
16 return
17 }
18
19 // Call Turalogin API to verify the token
20 payload, _ := json.Marshal(map[string]string{
21 "sessionId": token,
22 })
23
24 httpReq, _ := http.NewRequest("POST", turaloginURL+"/auth/verify", bytes.NewBuffer(payload))
25 httpReq.Header.Set("Authorization", "Bearer "+turaloginAPIKey)
26 httpReq.Header.Set("Content-Type", "application/json")
27
28 client := &http.Client{}
29 resp, err := client.Do(httpReq)
30 if err != nil {
31 http.Redirect(w, r, "/login?error=server_error", http.StatusFound)
32 return
33 }
34 defer resp.Body.Close()
35
36 if resp.StatusCode != http.StatusOK {
37 http.Redirect(w, r, "/login?error=verification_failed", http.StatusFound)
38 return
39 }
40
41 var result VerifyAuthResponse
42 json.NewDecoder(resp.Body).Decode(&result)
43
44 // Create session cookie (using your session package)
45 sessionToken := createSession(result.User.ID, result.User.Email)
46
47 http.SetCookie(w, &http.Cookie{
48 Name: "session",
49 Value: sessionToken,
50 HttpOnly: true,
51 Secure: true,
52 SameSite: http.SameSiteLaxMode,
53 MaxAge: 7 * 24 * 60 * 60, // 7 days
54 Path: "/",
55 })
56
57 http.Redirect(w, r, "/dashboard", http.StatusFound)
58}

4. Turalogin Client

A reusable client struct for Turalogin API calls.

turalogin/client.go
1package turalogin
2
3import (
4 "bytes"
5 "encoding/json"
6 "fmt"
7 "net/http"
8)
9
10type Client struct {
11 apiKey string
12 validationURL string
13 baseURL string
14 http *http.Client
15}
16
17type User struct {
18 ID string `json:"id"`
19 Email string `json:"email"`
20}
21
22type AuthResult struct {
23 Token string `json:"token"`
24 User User `json:"user"`
25}
26
27type Error struct {
28 Message string
29 Code string
30 Status int
31}
32
33func (e *Error) Error() string {
34 return e.Message
35}
36
37func NewClient(apiKey, validationURL string) *Client {
38 return &Client{
39 apiKey: apiKey,
40 validationURL: validationURL,
41 baseURL: "https://api.turalogin.com/api/v1",
42 http: &http.Client{},
43 }
44}
45
46func (c *Client) StartAuth(email string) error {
47 payload, _ := json.Marshal(map[string]string{
48 "email": email,
49 "validationUrl": c.validationURL,
50 })
51
52 req, _ := http.NewRequest("POST", c.baseURL+"/auth/start", bytes.NewBuffer(payload))
53 req.Header.Set("Authorization", "Bearer "+c.apiKey)
54 req.Header.Set("Content-Type", "application/json")
55
56 resp, err := c.http.Do(req)
57 if err != nil {
58 return err
59 }
60 defer resp.Body.Close()
61
62 if resp.StatusCode != http.StatusOK {
63 var result map[string]interface{}
64 json.NewDecoder(resp.Body).Decode(&result)
65 return &Error{
66 Message: fmt.Sprintf("%v", result["error"]),
67 Code: fmt.Sprintf("%v", result["code"]),
68 Status: resp.StatusCode,
69 }
70 }
71
72 return nil
73}
74
75func (c *Client) VerifyToken(sessionID string) (*AuthResult, error) {
76 payload, _ := json.Marshal(map[string]string{
77 "sessionId": sessionID,
78 })
79
80 req, _ := http.NewRequest("POST", c.baseURL+"/auth/verify", bytes.NewBuffer(payload))
81 req.Header.Set("Authorization", "Bearer "+c.apiKey)
82 req.Header.Set("Content-Type", "application/json")
83
84 resp, err := c.http.Do(req)
85 if err != nil {
86 return nil, err
87 }
88 defer resp.Body.Close()
89
90 if resp.StatusCode != http.StatusOK {
91 var errResult map[string]interface{}
92 json.NewDecoder(resp.Body).Decode(&errResult)
93 return nil, &Error{
94 Message: fmt.Sprintf("%v", errResult["error"]),
95 Code: fmt.Sprintf("%v", errResult["code"]),
96 Status: resp.StatusCode,
97 }
98 }
99
100 var result AuthResult
101 json.NewDecoder(resp.Body).Decode(&result)
102
103 return &result, nil
104}

5. Authentication Middleware

Middleware to protect routes and validate sessions.

middleware/auth.go
1package middleware
2
3import (
4 "context"
5 "net/http"
6)
7
8type contextKey string
9
10const UserContextKey contextKey = "user"
11
12type User struct {
13 ID string
14 Email string
15}
16
17func RequireAuth(next http.Handler) http.Handler {
18 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
19 cookie, err := r.Cookie("session")
20 if err != nil {
21 http.Error(w, `{"error": "Authentication required"}`, http.StatusUnauthorized)
22 return
23 }
24
25 // Validate session token (implement your session validation)
26 user, err := validateSession(cookie.Value)
27 if err != nil {
28 http.Error(w, `{"error": "Invalid session"}`, http.StatusUnauthorized)
29 return
30 }
31
32 // Add user to context
33 ctx := context.WithValue(r.Context(), UserContextKey, user)
34 next.ServeHTTP(w, r.WithContext(ctx))
35 })
36}
37
38func GetUser(r *http.Request) *User {
39 user, ok := r.Context().Value(UserContextKey).(*User)
40 if !ok {
41 return nil
42 }
43 return user
44}
45
46func validateSession(token string) (*User, error) {
47 // Implement your session validation logic
48 // This could be JWT validation, database lookup, etc.
49 return &User{ID: "...", Email: "..."}, nil
50}

Complete Go Application

A complete Go application with magic link authentication and middleware.

main.go
1package main
2
3import (
4 "encoding/json"
5 "log"
6 "net/http"
7 "os"
8
9 "myapp/handlers"
10 "myapp/middleware"
11 "myapp/turalogin"
12)
13
14var client *turalogin.Client
15
16func main() {
17 // Initialize Turalogin client
18 client = turalogin.NewClient(
19 os.Getenv("TURALOGIN_API_KEY"),
20 os.Getenv("APP_LOGIN_VALIDATION_URL"),
21 )
22
23 // Create router
24 mux := http.NewServeMux()
25
26 // Public auth routes
27 mux.HandleFunc("POST /auth/start", handlers.StartAuth)
28 mux.HandleFunc("GET /auth/callback", handlers.AuthCallback)
29 mux.HandleFunc("POST /auth/logout", handlers.Logout)
30
31 // Protected routes (with auth middleware)
32 protected := http.NewServeMux()
33 protected.HandleFunc("GET /api/me", handleMe)
34 protected.HandleFunc("GET /api/dashboard", handleDashboard)
35
36 mux.Handle("/api/", middleware.RequireAuth(protected))
37
38 // Start server
39 log.Println("Server starting on :8080")
40 log.Fatal(http.ListenAndServe(":8080", mux))
41}
42
43func handleMe(w http.ResponseWriter, r *http.Request) {
44 user := middleware.GetUser(r)
45
46 w.Header().Set("Content-Type", "application/json")
47 json.NewEncoder(w).Encode(map[string]interface{}{
48 "id": user.ID,
49 "email": user.Email,
50 })
51}
52
53func handleDashboard(w http.ResponseWriter, r *http.Request) {
54 user := middleware.GetUser(r)
55
56 w.Header().Set("Content-Type", "application/json")
57 json.NewEncoder(w).Encode(map[string]interface{}{
58 "message": "Welcome to the dashboard, " + user.Email + "!",
59 })
60}
61
62// handlers/auth.go - Logout handler
63func Logout(w http.ResponseWriter, r *http.Request) {
64 http.SetCookie(w, &http.Cookie{
65 Name: "session",
66 Value: "",
67 HttpOnly: true,
68 Secure: true,
69 MaxAge: -1,
70 Path: "/",
71 })
72
73 w.Header().Set("Content-Type", "application/json")
74 json.NewEncoder(w).Encode(map[string]bool{"success": true})
75}

Ready to integrate?

Create your Turalogin account and get your API key in minutes.