JWT Authentication

Generate JWT token

  1. Use PortOne secret key to generate JWT token

  2. Algorithm used for generating token - "HS256"

  3. Payload/claims to encode for generating token

    {
        "iss": "PORTONE",
        "sub": "SglffyyZgojEdXWL",
        "iat": 1516239022,
        "exp": 1516239122
    }
    
    ParameterDescriptionValues
    issIssuerDefault Value: "PORTONE"
    subSubjectPortOne Key
    iatIssued Timestamp in secTimestamp in sec
    expExpiry Timestamp in secTimestamp in sec+100
  4. Add following Headers in request as shown in below request -

    X-Portone-Client-Key:  PortOne_Client_Key
    Authorization: Bearer token
    
  5. Sample curl request

    curl --location --request GET 'https://api.portone.cloud/api/payout/va/902000225690/balance' \
    --header 'X-Portone-Client-Key: SglffyyZgojEdXWL' \
    --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJDSEFJUEFZIiwic3ViIjoiY2hhaXBheV9jbGllbnRfaWQiLCJpYXQiOjE1MTYyMzkwMjIsImV4cCI6MTgzMDQwMDMxNn0.CJHQTY-6v5ILILamo13BhVdgK68AIH1oPwXYH4Iyffs' \
    --data-raw ''
    

Sample code to generate JWT token

<Tabs
defaultValue="golang"
values={[
{ label: 'Golang', value: 'golang', },
{ label: 'JavaScript', value: 'javascript', },
{ label: 'PHP', value: 'php', },
{ label: 'NodeJS', value: 'nodejs', },
{ label: 'C#', value: 'C#', },
{ label: 'Java', value: 'Java', },
{ label: 'Python', value: 'python', },
]}>

package main

import (
    "fmt"
    "time"
    "github.com/dgrijalva/jwt-go"
)

func GenerateToken(jwtKey []byte) string {

    cur := time.Now()
    expirationTime := cur.Add(100 * time.Second)
    // Create the JWT claims, which includes the username and expiry time
    claims := jwt.StandardClaims{
        // In JWT, the expiry time is expressed as unix milliseconds
        Issuer:    "PORTONE",
        Subject:   "PortOne Client Key",
        IssuedAt:  cur.Unix(),
        ExpiresAt: expirationTime.Unix(),
    }

    // Declare the token with the algorithm used for signing, and the claims
    token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
    // Create the JWT string
    tokenString, _ := token.SignedString(jwtKey)
    return tokenString

}

func main() {
    jwtKey := []byte("my_secret_key")
    fmt.Println(GenerateToken(jwtKey))
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/hmac-sha256.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/enc-base64.min.js"></script>

<script type="text/javascript">

function getJWTToken(){
    var header = {
        "alg": "HS256",
        "typ": "JWT"
    };

    var stringifiedHeader = CryptoJS.enc.Utf8.parse(JSON.stringify(header));
    var encodedHeader = base64url(stringifiedHeader);

    var timeNow = parseInt(new Date().getTime()/1000);

    var data = {
        "sub": "PortOne Client Key",
        "iss": "PORTONE",
        "iat": timeNow,
        "exp": timeNow+100,
    };

    var stringifiedData = CryptoJS.enc.Utf8.parse(JSON.stringify(data));
    var encodedData = base64url(stringifiedData);

    var token = encodedHeader + "." + encodedData;

    var secret = "PortOne Secret Key";

    var signature = CryptoJS.HmacSHA256(token, secret);
    signature = base64url(signature);

    var signedToken = token + "." + signature;

    return signedToken;
}

let jwt_token = getJWTToken();

</script>
<?php
function base64url($source) {
    // Encode in classical base64
    $encodedSource = base64_encode($source);

    // Remove padding equal characters
    $encodedSource = rtrim($encodedSource, '=');

    // Replace characters according to base64url specifications
    $encodedSource = str_replace(['+', '/'], ['-', '_'], $encodedSource);

    return $encodedSource;
}

function generateJWTToken() {
    $key = "PortOneKey";
    $secret_key = "PortOneSecret";

    $header = [
        'alg' => 'HS256',
        'typ' => 'JWT'
    ];
    $stringifiedHeader = json_encode($header);
    $encodedHeader = base64url($stringifiedHeader);

    $timeNow = time();

    $data = [
        'iss' => 'PORTONE',
        'sub' => $key,
        'iat' => $timeNow,
        'exp' => $timeNow + 100
    ];
    $stringifiedData = json_encode($data);
    $encodedData = base64url($stringifiedData);

    $token = $encodedHeader . "." . $encodedData;
    $signature = base64url(hash_hmac('sha256', $token, $secret_key, true));

    $signedToken = $token . "." . $signature;

    return $signedToken;
}

function main() {
    $jwtToken = generateJWTToken();
    echo "JWT Token: " . $jwtToken;
}

main()
?>

function base64url(source) {
	// Encode in classical base64
	encodedSource = CryptoJS.enc.Base64.stringify(source)

	// Remove padding equal characters
	encodedSource = encodedSource.replace(/=+$/, '')

	// Replace characters according to base64url specifications
	encodedSource = encodedSource.replace(/\+/g, '-')
	encodedSource = encodedSource.replace(/\//g, '_')

	return encodedSource
}

function getJWTToken(portOnekey,portOneSecret){
	var header = {
		"alg": "HS256",
		"typ": "JWT"
	};

	var stringifiedHeader = CryptoJS.enc.Utf8.parse(JSON.stringify(header));
	var encodedHeader = base64url(stringifiedHeader);

	var timeNow = parseInt(new Date().getTime()/1000);

	var data = {
		"sub": portOnekey,
		"iss": "PORTONE",
		"iat": timeNow,
		"exp": timeNow+100,
	};

	var stringifiedData = CryptoJS.enc.Utf8.parse(JSON.stringify(data));
	var encodedData = base64url(stringifiedData);

	var token = encodedHeader + "." + encodedData;

	var secret  = portOneSecret

	var signature = CryptoJS.HmacSHA256(token, secret);
	signature = base64url(signature);

	var signedToken = token + "." + signature;
	return signedToken;
}

getJWTToken( KEY, SECRET )

using System;
using System.Text;
using System.Security.Cryptography;
using Newtonsoft.Json;

public class Base64Url
{
    public static string Encode(byte[] source)
    {
        // Encode in classical base64
        string encodedSource = Convert.ToBase64String(source);

        // Remove padding equal characters
        encodedSource = encodedSource.TrimEnd('=');

        // Replace characters according to base64url specifications
        encodedSource = encodedSource.Replace('+', '-');
        encodedSource = encodedSource.Replace('/', '_');

        return encodedSource;
    }
}

public class JWTGenerator
{
    public static string GetJWTToken(string portOnekey, string portOneSecret)
    {
        var header = new
        {
            alg = "HS256",
            typ = "JWT"
        };

        var stringifiedHeader = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(header));
        var encodedHeader = Base64Url.Encode(stringifiedHeader);

        var timeNow = (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;

        var data = new
        {
            sub = portOnekey,
            iss = "PORTONE",
            iat = timeNow,
            exp = timeNow + 100,
        };

        var stringifiedData = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(data));
        var encodedData = Base64Url.Encode(stringifiedData);

        var token = encodedHeader + "." + encodedData;

        var secret = Encoding.UTF8.GetBytes(portOneSecret);

        using (var hmac = new HMACSHA256(secret))
        {
            var signatureBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(token));
            var signature = Base64Url.Encode(signatureBytes);

            var signedToken = token + "." + signature;
            return signedToken;
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        string key = "KEY";
        string secret = "SECRET";
        string jwtToken = JWTGenerator.GetJWTToken(key, secret);
        Console.WriteLine(jwtToken);
    }
}
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class JWTGenerator {

    public static String base64url(byte[] source) {
        // Encode in classical base64
        String encodedSource = Base64.getEncoder().encodeToString(source);

        // Remove padding equal characters
        encodedSource = encodedSource.replaceAll("=+$", "");

        // Replace characters according to base64url specifications
        encodedSource = encodedSource.replace("+", "-");
        encodedSource = encodedSource.replace("/", "_");

        return encodedSource;
    }

    public static String generateJWTToken() {
        String key = "PortOneKey";
        String secretKey = "PortOneSecret";

        // Header
        String header = "{\"alg\":\"HS256\",\"typ\":\"JWT\"}";
        byte[] stringifiedHeader = header.getBytes(StandardCharsets.UTF_8);
        String encodedHeader = base64url(stringifiedHeader);

        // Payload
        long timeNow = System.currentTimeMillis() / 1000;

        String payload = "{\"iss\":\"PORTONE\",\"sub\":\"" + key + "\",\"iat\":" + timeNow + ",\"exp\":" + (timeNow + 1000000) + "}";
        byte[] stringifiedPayload = payload.getBytes(StandardCharsets.UTF_8);
        String encodedData = base64url(stringifiedPayload);

        // Token
        String token = encodedHeader + "." + encodedData;

        // Signature
        try {
            Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
            SecretKeySpec secret_key = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
            sha256_HMAC.init(secret_key);

            byte[] signatureBytes = sha256_HMAC.doFinal(token.getBytes(StandardCharsets.UTF_8));
            String signature = base64url(signatureBytes);

            // Signed Token
            return token + "." + signature;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static void main(String[] args) {
        String jwtToken = generateJWTToken();
        System.out.println("JWT Token: " + jwtToken);
    }
}

import base64
import json
import hashlib
import hmac
import time

def base64url(source):
    # Remove padding equal characters
    encoded_source = base64.b64encode(source).decode().rstrip("=")

    # Replace characters according to base64url specifications
    encoded_source = encoded_source.replace("+", "-").replace("/", "_")

    return encoded_source

def generate_jwt_token():
    key = "PortOneKey"
    secret_key = "PortOneSecret"

    # Header
    header = {
        'alg': 'HS256',
        'typ': 'JWT'
    }
    stringified_header = json.dumps(header)
    encoded_header = base64url(stringified_header.encode())

    # Payload
    time_now = int(time.time())
    data = {
        'iss': 'PORTONE',
        'sub': key,
        'iat': time_now,
        'exp': time_now + 100
    }
    stringified_data = json.dumps(data)
    encoded_data = base64url(stringified_data.encode())

    # Token
    token = f"{encoded_header}.{encoded_data}"

    # Signature
    signature = base64url(hmac.new(secret_key.encode(), token.encode(), hashlib.sha256).digest())

    # Signed Token
    signed_token = f"{token}.{signature}"

    return signed_token

def main():
    jwt_token = generate_jwt_token()
    print("JWT Token:", jwt_token)

if __name__ == "__main__":
    main()