Json Web Token / oauth_token / auth_token
-
What?
This is open standard (RFC 7519) used for securely transmitting information between two parties as a JSON object.
Mostly used for authentication.
Usage? For authentication on the web, ie authentication to RESTFul API
Disecting token
-
JWTs consist of three parts: header + payload + signature, concatenated by dot .
jwt-token = header.payload.signature
{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6IiIsImV4cCI6MTc0MDU1OTk2NX0.Dck0cV04Vv7G6ciMt2qvE5_fS2ZMpl5aFuXwKNnD3M0"}
How header, payload, Signature are calculated?
- A JWT is assigned to user as a authentication token
Header = Base64encode(algo+type)
struct st = {
"alg": "HS256",
"typ": "JWT",
}
header = base64Encode(st)
Payload = Base64encode(email+timestamp)
struct st = {
"email": email,
"exp": timestamp_to_expiry
}
payload = base64Encode(st)
Signature
HMAC_SHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
Complete Code
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"fmt"
"strings"
"time"
)
var jwtSecret = []byte("your-secret-key") // Use the same secret key
// Function to base64 URL encode a string
func base64UrlEncode(data []byte) string {
return strings.TrimRight(base64.URLEncoding.EncodeToString(data), "=")
}
// Function to create JWT header manually
func JWTHeader() string {
header := map[string]string{
"alg": "HS256",
"typ": "JWT",
}
headerJSON, _ := json.Marshal(header)
return base64UrlEncode(headerJSON)
}
// Function to create JWT payload manually
func JWTPayload(email string) string {
payload := map[string]interface{}{
"email": email,
"exp": time.Now().Add(time.Hour * 24).Unix(), // 24-hour expiry
}
payloadJSON, _ := json.Marshal(payload)
return base64UrlEncode(payloadJSON)
}
// Function to create JWT signature manually
func JWTSignature(email string) string {
headerEncoded := JWTHeader()
payloadEncoded := JWTPayload(email)
signatureInput := headerEncoded + "." + payloadEncoded
h := hmac.New(sha256.New, jwtSecret)
h.Write([]byte(signatureInput))
return base64UrlEncode(h.Sum(nil))
}
func generateManualJWT(email string, owner bool) string {
return JWTHeader() + "." + JWTPayload(email) + "." + JWTSignature(email)
}
func main() {
jwt := generateManualJWT("test@example.com")
fmt.Println("Generated JWT:", jwt)
}
How JWTs are used for authentication
sequenceDiagram rect rgb(236, 232, 242) participant dns as DNS participant cdn as CDN participant ub as User-Browser box AWS participant lb as LoadBalancer participant as as Application Server
RESTFul Service participant auth as Auth_Service end participant idp as IDP note over ub: HTTP GET test.com ub ->> dns: IP of test.com dns ->> ub: IP of CDN ub ->> cdn: HTTP GET test.com cdn ->> ub: Home Page note over ub: User enters username,pass ub ->> lb: HTTP GET test.com(user,pass) lb ->> as: HTTP GET test.com(user,pass) as ->> ub: HTTP Redirect http://auth_svc ub ->> auth: http://auth_svc?user?pass auth ->> idp: ?user?pass idp ->> auth: SAML Assertion(Authenticated) auth ->> ub: JWT Token(Json Object) note over auth:JWT=(header + payload(username)
+ signature(Digital signature of payload)) note over ub: Stores JWT in cookie or cache ub ->> as: CRUD(header(bearer token=JWT) + Body) note over as: JWT expiry in 5 hours
Reissue JWT end