A simple JWT package.
package main
import (
"fmt"
"github.com/xyproto/simplejwt"
)
func main() {
// Set the secret that is used for generating and validating JWT tokens
simplejwt.SetSecret("server-secret-goes-here")
// Generate a token by passing in a subject and for how many seconds the token should last
token := simplejwt.SimpleGenerate("[email protected]", 3600)
if token == "" {
fmt.Println("Failed to generate token")
return
}
fmt.Printf("Generated token: %s\n", token)
// Validate the token
decodedSubject := simplejwt.SimpleValidate(token)
if decodedSubject == "" {
fmt.Println("Failed to validate token")
return
}
fmt.Printf("Decoded payload, got subject: %s\n", decodedSubject)
}
package main
import (
"fmt"
"time"
"github.com/xyproto/simplejwt"
)
func main() {
// Set the JWT secret
simplejwt.SetSecret("server-secret-goes-here")
// Generate a token
payload := simplejwt.Payload{
Subject: "1234567890",
Expires: time.Now().Add(time.Hour),
}
token, err := simplejwt.Generate(payload, nil)
if err != nil {
fmt.Printf("Failed to generate token: %v\n", err)
return
}
fmt.Printf("Generated token: %s\n", token)
// Validate the token
decodedPayload, err := simplejwt.Validate(token)
if err != nil {
fmt.Printf("Failed to validate token: %v\n", err)
return
}
fmt.Printf("Decoded payload: %+v\n", decodedPayload)
}
Subject
is the user or system that the token is about.Expires
is the expiration time of the token.This example is also available as cmd/simple/main.go
.
This is a simple HTTP server that can be accessed in a browser as http://localhost:4000
.
It has the following endpoints:
/
- a HTML page with instructions for how to use curl
./generate
- for generating a JWT token./protected
- for retrieving protected data, but only if it is also given a valid JWT token.package main
import (
"fmt"
"net/http"
"strings"
"time"
"github.com/xyproto/simplejwt"
)
func generateHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
payload := simplejwt.Payload{
Subject: "1234567890",
Expires: time.Now().Add(time.Hour),
}
token, err := simplejwt.Generate(payload, nil)
if err != nil {
http.Error(w, "Error generating token", http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "text/plain")
w.Write([]byte(token))
}
func protectedHandler(w http.ResponseWriter, r *http.Request) {
authHeader := r.Header.Get("Authorization")
if authHeader == "" {
http.Error(w, "Authorization header not provided", http.StatusUnauthorized)
return
}
token := strings.TrimPrefix(authHeader, "Bearer ")
if token == "" {
http.Error(w, "Token not provided", http.StatusUnauthorized)
return
}
_, err := simplejwt.Validate(token)
if err != nil {
http.Error(w, "Invalid or expired token", http.StatusUnauthorized)
return
}
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{"message": "Access granted to protected data."}`))
}
func rootHandler(w http.ResponseWriter, r *http.Request) {
html := `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Simple JWT Example</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 1rem;
}
pre {
background-color: #f5f5f5;
padding: 0.5rem;
overflow-x: scroll;
}
</style>
</head>
<body>
<h1>Simple JWT Example</h1>
<p>Use the following curl commands to interact with the server:</p>
<h2>1. Generate a JWT token</h2>
<p>Send a POST request to <code>/generate</code> to generate a JWT token:</p>
<pre>curl -X POST http://localhost:4000/generate</pre>
<h2>2. Access protected data</h2>
<p>Send a GET request to <code>/protected</code> with the token in the Authorization header to access protected data:</p>
<pre>curl -H "Authorization: Bearer <your_token_here>" http://localhost:4000/protected</pre>
<p>Replace <code><your_token_here></code> with the token you received from the previous command.</p>
</body>
</html>
`
w.Header().Set("Content-Type", "text/html")
w.Write([]byte(html))
}
func main() {
http.HandleFunc("/", rootHandler)
http.HandleFunc("/generate", generateHandler)
http.HandleFunc("/protected", protectedHandler)
fmt.Println("Server running on :4000")
http.ListenAndServe(":4000", nil)
}
This example is also available as cmd/server/main.go
.
A simple chat application that uses Go for the backend and a vanilla JS SPA as the front end is available in cmd/kawaiichat
.
To try it out, just enter the cmd/kawaiichat
directory, run go build -mod=vendor && ./kawaiichat
and then visit http://localhost:8080
in a browser.
Screenshot: