Quickstart — Go
Verify HelloJohn tokens in your Go backend in 10 minutes. Works with net/http, Gin, Echo, Chi, and any Go HTTP framework.
Time: ~10 minutes Prerequisites: A HelloJohn account (Cloud) or a self-hosted server running locally. Go 1.21+.
Install the SDK
go get github.com/hellojohn/hellojohn-goInitialize the client
package auth
import (
"os"
hellojohn "github.com/hellojohn/hellojohn-go"
)
var Client *hellojohn.Client
func init() {
Client = hellojohn.New(hellojohn.Config{
SecretKey: os.Getenv("HELLOJOHN_SECRET_KEY"),
})
}Your Secret Key must never be hardcoded or committed to version control. Use environment variables or a secrets manager.
Verify a token (net/http middleware)
package middleware
import (
"context"
"net/http"
"strings"
"myapp/internal/auth"
)
type contextKey string
const UserIDKey contextKey = "userID"
func RequireAuth(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
authHeader := r.Header.Get("Authorization")
if !strings.HasPrefix(authHeader, "Bearer ") {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
token := strings.TrimPrefix(authHeader, "Bearer ")
payload, err := auth.Client.VerifyToken(r.Context(), token)
if err != nil {
http.Error(w, "Invalid token", http.StatusUnauthorized)
return
}
ctx := context.WithValue(r.Context(), UserIDKey, payload.Subject)
next.ServeHTTP(w, r.WithContext(ctx))
})
}Use the middleware in your router:
package main
import (
"net/http"
"myapp/internal/middleware"
)
func main() {
mux := http.NewServeMux()
protected := http.NewServeMux()
protected.HandleFunc("/profile", profileHandler)
mux.Handle("/api/", middleware.RequireAuth(http.StripPrefix("/api", protected)))
http.ListenAndServe(":8080", mux)
}Verify a token (Gin middleware)
package middleware
import (
"net/http"
"strings"
"github.com/gin-gonic/gin"
"myapp/internal/auth"
)
func GinRequireAuth() gin.HandlerFunc {
return func(c *gin.Context) {
authHeader := c.GetHeader("Authorization")
if !strings.HasPrefix(authHeader, "Bearer ") {
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"})
return
}
token := strings.TrimPrefix(authHeader, "Bearer ")
payload, err := auth.Client.VerifyToken(c.Request.Context(), token)
if err != nil {
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "invalid token"})
return
}
c.Set("userID", payload.Subject)
c.Next()
}
}Read the user ID in a handler
package handlers
import (
"encoding/json"
"net/http"
"myapp/internal/middleware"
)
func ProfileHandler(w http.ResponseWriter, r *http.Request) {
userID, ok := r.Context().Value(middleware.UserIDKey).(string)
if !ok {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]string{
"user_id": userID,
})
}How token verification works
HelloJohn issues EdDSA-signed JWTs. VerifyToken():
- Fetches and caches your instance's JWKS endpoint (thread-safe)
- Verifies the EdDSA signature using the public key
- Validates expiry (
exp), issuer (iss), and audience (aud) claims - Returns the decoded
*jwt.Payload— zero database calls
The JWKS is refreshed automatically when a key rotation is detected.
Next steps
Quickstart — Python
Verify HelloJohn tokens in your Python backend in 10 minutes. Works with FastAPI, Django, Flask, and any WSGI/ASGI framework.
Quickstart — React Native
Add HelloJohn authentication to your React Native app with Expo. Sign in, protect screens, and manage sessions with the useAuth hook.