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:

Understanding the JWT Generation Concept

A JWT consists of three parts:

Header.Payload.Signature

Header

Contains metadata such as:

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

  1. Serialize header to JSON.

  2. Serialize payload to JSON.

  3. Base64Url encode both values.

  4. Combine them using a dot separator.

  5. Sign the combined string using HMACSHA256 with a secret key.

  6. 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:

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

Advantages

Disadvantages

Second Method: Generic Version

Usage Example

private async Task GetMaxAmount(string uid)
{
    try
    {
        LogError("API CALL STARTED for UID: " + uid);

        var requestObj = new RequestRoot
        {
            req = new List<Request>
            {
                new Request
                {
                    ID = uid,
                    clientid = uid
                }
            }
        };

        string jwtToken = GenerateJwtToken(requestObj);
    }
}

Generic Method

private string GenerateJwtToken<T>(T requestObj)
{
    var header = new { alg = "HS256", typ = "JWT" };

    string headerBase64 = Base64UrlEncode(
        Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(header)));

    string payloadBase64 = Base64UrlEncode(
        Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(requestObj)));

    string unsignedToken = headerBase64 + "." + payloadBase64;

    using (var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secretKey)))
    {
        string signature = Base64UrlEncode(
            hmac.ComputeHash(Encoding.UTF8.GetBytes(unsignedToken)));

        return unsignedToken + "." + signature;
    }
}

This version uses generics and can accept any model type.

Characteristics

Advantages

Disadvantages

Are Both Methods Based on the Same Concept?

Yes. Both methods follow the same JWT encoding concept:

The cryptographic logic is identical. The difference lies only in method design and flexibility.

Key Differences Between the Two

Type Handling

Reusability

Scalability

Code Maintainability

Which One Is Better?

For small applications with only one request model, the non-generic method is acceptable.

For scalable applications, enterprise systems, or projects that call multiple APIs, the generic version is better.

The generic version follows better software design principles:

In most professional scenarios, the generic method is the better choice.

Important Security Consideration

Although both methods manually implement JWT creation, in production environments it is recommended to use official libraries such as:

System.IdentityModel.Tokens.Jwt

Using a standard library reduces the risk of cryptographic mistakes and ensures compliance with JWT standards.

Conclusion

Both versions of GenerateJwtToken are built on the same JWT encoding and signing concept using HS256 and HMACSHA256. The real difference lies in flexibility and reusability.

The non-generic method is suitable for single-purpose implementations.
The generic method is more scalable, reusable, and aligned with modern ASP.NET development practices.

If your application is expected to grow or handle multiple request types, the generic GenerateJwtToken method is the more professional and future-ready approach.