Introduction
In ASP.NET applications that integrate with secure APIs, JSON Web Tokens (JWT) are commonly used to authenticate requests. A JWT ensures that request data is signed and cannot be modified without detection.
In this scenario, there are two versions of the GenerateJwtToken method. Both share the same core concept: encoding and signing a JWT using the HS256 algorithm, but they differ in flexibility, design, and reusability.
This article explains:
The concept behind JWT generation
The purpose of these methods
Their differences
Which approach is better, depending on the scenario
Understanding the JWT Generation Concept
A JWT consists of three parts:
Header.Payload.Signature
Header
Contains metadata such as:
Algorithm (HS256)
Token type (JWT)
Payload
Contains the request data or claims that need to be securely transmitted.
Signature
Created using HMACSHA256 and a secret key to ensure integrity and authenticity.
JWT Generation Process
Serialize header to JSON.
Serialize payload to JSON.
Base64Url encode both values.
Combine them using a dot separator.
Sign the combined string using HMACSHA256 with a secret key.
Append the signature to produce the final token.
Both methods follow this exact process.
Purpose of GenerateJwtToken in ASP.NET
Generating a JWT in ASP.NET is required:
To securely send request data to an external API.
To allow the API to verify authenticity.
To prevent tampering with request parameters.
To implement stateless authentication.
Without this token generation process, the API cannot verify whether the request is trusted.
First Method: Non-Generic Version
Models
public class RequestRoot
{
public List<PayoutRequest> req { get; set; }
}
public class Request
{
public string ID { get; set; }
public string clientid { get; set; }
}
Method Implementation
private string GenerateJwtToken(RequestRoot requestObj)
{
var header = new { alg = "HS256", typ = "JWT" };
var payload = requestObj;
string headerJson = JsonConvert.SerializeObject(header);
string payloadJson = JsonConvert.SerializeObject(payload);
string headerBase64 = Base64UrlEncode(Encoding.UTF8.GetBytes(headerJson));
string payloadBase64 = Base64UrlEncode(Encoding.UTF8.GetBytes(payloadJson));
string unsignedToken = headerBase64 + "." + payloadBase64;
var keyBytes = Encoding.UTF8.GetBytes(secretKey);
using (var hmac = new HMACSHA256(keyBytes))
{
var signatureBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(unsignedToken));
string signature = Base64UrlEncode(signatureBytes);
return unsignedToken + "." + signature;
}
}
This version is tightly coupled to a specific request type.
Characteristics
Accepts only one specific model type.
Explicit header and payload handling.
Slightly more readable for beginners.
Suitable for single-purpose implementations.
Advantages
Clear structure.
Easier debugging.
Strong type safety for a specific business case.

Join the conversation! Your thoughts help the community grow.