v1.0.3

Getting Started

Last updated


This page goes from install to a working protected route: start Redis, create JWTAuth, log in, access, log out.

Prerequisites


ItemVersion
Go1.24 or higher (go.mod declares go 1.24.3)
RedisAny version supporting SETEX/SETNX/EVAL/MULTI (CI uses redis:7-alpine)
GinOnly when using GinMiddleware()

Installation


  1. go get github.com/pardnchiu/go-jwt@latest

The package lives in the core/ subdirectory with package name goJwt. Since v1.0.3 the import path is github.com/pardnchiu/go-jwt/core; see Removed API for the old-path symbol mapping.
  1. import goJwt "github.com/pardnchiu/go-jwt/core"

Start Redis


  1. docker run -d --name redis -p 6379:6379 redis:7-alpine

First Server


  1. package main
  2. import (
  3. "encoding/json"
  4. "log"
  5. "net/http"
  6. goJwt "github.com/pardnchiu/go-jwt/core"
  7. )
  8. func main() {
  9. auth, err := goJwt.New(goJwt.Config{
  10. Redis: goJwt.Redis{Host: "localhost", Port: 6379},
  11. })
  12. if err != nil {
  13. log.Fatalf("failed to init go-jwt: %v", err)
  14. }
  15. defer auth.Close()
  16. mux := http.NewServeMux()
  17. mux.HandleFunc("POST /login", func(w http.ResponseWriter, r *http.Request) {
  18. result := auth.Create(w, r, &goJwt.Auth{ID: "u_001", Name: "Pardn", Email: "dev@example.com"})
  19. if !result.Success {
  20. http.Error(w, result.Error, result.StatusCode)
  21. return
  22. }
  23. w.Header().Set("Content-Type", "application/json")
  24. json.NewEncoder(w).Encode(result.Token)
  25. })
  26. mux.Handle("GET /me", auth.HTTPMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  27. user, ok := goJwt.GetAuthDataFromHTTPRequest(r)
  28. if !ok {
  29. http.Error(w, "unauthorized", http.StatusUnauthorized)
  30. return
  31. }
  32. w.Header().Set("Content-Type", "application/json")
  33. json.NewEncoder(w).Encode(user)
  34. })))
  35. mux.HandleFunc("POST /logout", func(w http.ResponseWriter, r *http.Request) {
  36. result := auth.Revoke(w, r)
  37. if !result.Success {
  38. http.Error(w, result.Error, result.StatusCode)
  39. return
  40. }
  41. w.WriteHeader(http.StatusNoContent)
  42. })
  43. log.Fatal(http.ListenAndServe(":8080", mux))
  44. }

On first start, when no keys are configured and no PEM files exist under ./keys/, New() generates a P-256 key pair into ./keys/private-key.pem and ./keys/public-key.pem (relative to the working directory). See Key Management.

Try the Flow


Use a cookie jar to mimic a browser. The User-Agent must be a recognizable browser string, or send a stable X-Device-FP; otherwise the fingerprint changes on every request (see Device Fingerprint):
  1. UA="Mozilla/5.0 (Macintosh; Intel Mac OS X 14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120 Safari/537.36"
  2. # Login: the response sets access_token, refresh_id, and conn.device.id cookies
  3. curl -s -A "$UA" -c jar.txt -b jar.txt -X POST http://localhost:8080/login
  4. # Access the protected route
  5. curl -s -A "$UA" -c jar.txt -b jar.txt http://localhost:8080/me
  6. # Logout: clears cookies and revokes the Access Token
  7. curl -s -A "$UA" -c jar.txt -b jar.txt -X POST http://localhost:8080/logout -o /dev/null -w "%{http_code}\n"

Next Steps


GoalPage
Understand Access Token, Refresh ID, and JTIToken Model
Tune lifetimes and cookie attributesConfiguration
Use GinMiddleware
Serve mobile apps or API clientsClient Integration
中文