Logo

dev-resources.site

for different kinds of informations.

JWT Tokens in Golang: A Developer’s Guide to Secure APIs

Published at
1/14/2025
Categories
programming
webdev
go
beginners
Author
kittipat1413
Categories
4 categories in total
programming
open
webdev
open
go
open
beginners
open
Author
12 person written this
kittipat1413
open
JWT Tokens in Golang: A Developer’s Guide to Secure APIs

JWT Image

Introduction

In modern web development, secure and scalable authentication is essential. JSON Web Tokens (JWT) have become a standard approach to achieving this. In this blog, we’ll explore what JWT is, how it works, and how to implement it in Golang.

What is a JWT?

A JSON Web Token (JWT) is a compact, URL-safe way of representing claims to be securely transferred between two parties. It is commonly used to authenticate and authorize users in APIs and distributed systems.

Structure of a JWT

A JWT consists of three parts separated by dots (.):

Header.Payload.Signature
Enter fullscreen mode Exit fullscreen mode

Example:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.reGQzG3OKdoIMWLDKOZ4TICJit3EW69cQE72E2CfzRE
Enter fullscreen mode Exit fullscreen mode

Each part is:
1.Header: Specifies the token type (JWT) and signing algorithm (HS256).

{
  "alg": "HS256",
  "typ": "JWT"
}
Enter fullscreen mode Exit fullscreen mode

2.Payload: Contains claims (user data like id, role, or name).

{
    "sub": "1234567890",
    "name": "John Doe",
    "admin": true,
    "iat": 1516239022
}
Enter fullscreen mode Exit fullscreen mode

3.Signature: Ensures the token’s integrity using a cryptographic signing process. Let’s explore this in detail.

The signature is created by:

  • Concatenating the Encoded Header and Payload:
  base64UrlEncode(header) + "." + base64UrlEncode(payload)
  • Signing the Result:
    • A cryptographic signing algorithm (e.g., HMACSHA256, RS256) is used with a secret or private key.
  • Appending the Signature: The final JWT becomes
  header.payload.signature

How JWT Works

  1. The client sends login credentials to the server.
  2. If valid, the server generates a JWT and returns it to the client.
  3. The client stores the JWT (e.g., in localStorage or cookies).
  4. For every request, the client includes the JWT in the Authorization header: Authorization: Bearer <token>
  5. The server validates the JWT on each request.
    • Recalculating the signature using the received header and payload.
    • Comparing the recalculated signature with the received signature.

Implementing JWT in Golang

Golang developers can leverage the excellent golang-jwt/jwt library for handling JWTs. This library provides robust features for creating, signing, and validating JWTs. You can find it here.

However, managing JWTs often requires repetitive tasks like configuring signing methods, parsing tokens, and validating claims. To simplify this, I’ve written a custom package that wraps the golang-jwt functionality. You can check out my package here.

Below is an example of how to use my custom JWT package.

package main

import (
    "context"
    "fmt"
    "log"
    "time"

    "github.com/golang-jwt/jwt/v5"
    jwtutil "github.com/kittipat1413/go-common/util/jwt"
)

type MyCustomClaims struct {
    jwt.RegisteredClaims
    UserID string `json:"uid"`
}

func main() {
    ctx := context.Background()
    signingKey := []byte("super-secret-key")
    manager, err := jwtutil.NewJWTManager(jwtutil.HS256, signingKey)
    if err != nil {
        log.Fatalf("Failed to create JWTManager: %v", err)
    }

    // Prepare custom claims
    claims := &MyCustomClaims{
        RegisteredClaims: jwt.RegisteredClaims{
            ExpiresAt: jwt.NewNumericDate(time.Now().Add(15 * time.Minute)),
            Issuer:    "example-HS256",
            Subject:   "example-subject",
        },
        UserID: "abc123",
    }

    // Create the token
    tokenStringHS256, err := manager.CreateToken(ctx, claims)
    if err != nil {
        log.Fatalf("Failed to create token: %v", err)
    }
    fmt.Println("Generated Token:", tokenStringHS256)

    // Validate the token
    parsedClaims := &MyCustomClaims{}
    err = manager.ParseAndValidateToken(ctx, tokenStringHS256, parsedClaims)
    if err != nil {
        log.Fatalf("Failed to validate token: %v", err)
    }

    fmt.Printf("Token is valid! UserID: %s, Issuer: %s\n", parsedClaims.UserID, parsedClaims.Issuer)
}
Enter fullscreen mode Exit fullscreen mode

You can explore the full implementation and documentation of my package on GitHub: here.

Best Practices for JWT

  1. Use HTTPS: Always transmit tokens over secure channels.
  2. Set Expiration Times: Include a reasonable exp to limit token misuse.
  3. Secure the Secret Key: Store keys securely using environment variables or secret managers.
  4. Avoid Sensitive Data in Payload: Only include non-critical information.
  5. Use Refresh Tokens: Pair JWT with refresh tokens to securely extend sessions.

Conclusion 🥂

JWT is a powerful tool for secure, stateless authentication. The signature ensures token integrity and authenticity, making JWT ideal for APIs and distributed systems. With libraries like jwt-go, you can easily implement JWT in your Golang projects.

☕ Support My Work ☕

If you enjoy my work, consider buying me a coffee! Your support helps me keep creating valuable content and sharing knowledge. ☕

Buy Me A Coffee

go Article's
30 articles in total
Favicon
A técnica dos dois ponteiros
Favicon
Preventing SQL Injection with Raw SQL and ORM in Golang
Favicon
🐹 Golang Integration with Kafka and Uber ZapLog 📨
Favicon
🌐 Building Golang RESTful API with Gin, MongoDB 🌱
Favicon
Golang e DSA
Favicon
Prevent Race Conditions Like a Pro with sync.Mutex in Go!
Favicon
tnfy.link - What's about ID?
Favicon
Developing a Simple RESTful API with Gin, ginvalidator, and validatorgo
Favicon
Desbravando Go: Capítulo 1 – Primeiros Passos na Linguagem
Favicon
Compile-Time Assertions in Go (Golang)
Favicon
Mastering GoFrame Logging: From Zero to Hero
Favicon
GoFr: An Opinionated Microservice Development Framework
Favicon
The Struggle of Finding a Free Excel to PDF Converter: My Journey and Solution
Favicon
Setting Up Your Go Environment
Favicon
External Merge Problem - Complete Guide for Gophers
Favicon
Mastering Go's encoding/json: Efficient Parsing Techniques for Optimal Performance
Favicon
Golang with Colly: Use Random Fake User-Agents When Scraping
Favicon
Versioning in Go Huma
Favicon
Go Basics: Syntax and Structure
Favicon
Interesting feedback on Fuego!
Favicon
Making Beautiful API Keys
Favicon
Building a Semantic Search Engine with OpenAI, Go, and PostgreSQL (pgvector)
Favicon
Go's Concurrency Decoded: Goroutine Scheduling
Favicon
Golang: Struct, Interface And Dependency Injection(DI)
Favicon
Desvendando Subprocessos: Criando um Bot de Música com Go
Favicon
go
Favicon
🚀 New Article Alert: Master sync.Pool in Golang! 🚀
Favicon
Week Seven Recap of #100DaysOfCode
Favicon
Ore: Advanced Dependency Injection Package for Go
Favicon
Golang vs C++: A Modern Alternative for High-Performance Applications

Featured ones: