Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generating JWT tokens

Could anyone provide me an example for generating jwt tokens with three headers given as (alg, kid, typ) that has the format:

{
  "alg": "RS256",
  "kid": "vpaas-magic-cookie-1fc542a3e4414a44b2611668195e2bfe/4f4910",
  "typ": "JWT"
}

under https://developer.8x8.com/jaas/docs/api-keys-jwt.

Jwt tokens get expired with a time limit of few hours so I am trying to find a way to generate the token in my code itself.

At the end, my javascript looks like this, where I add the jwt token inside the options list for authentication.

var options = {
                roomName: "vpaas-magic-cookie-secretKey/Room123",
                jwt: 'JWTTOKEN',
                ,

From what I have read under https://jwt.io/, I need the encoded key from the decoded details. As per the generating tokens, I think it uses HS256 algorithm. What are the steps to do this in javascript?

EDIT: After the user's answer, I did some changes to his code and I am currently generating half the JWT token. I am checking it with the already generated token on the server - Jaas.8x8

<script>
    const HMACSHA256 = (stringToSign, secret) => "not_implemented"

    // The header typically consists of two parts: 
    // the type of the token, which is JWT, and the signing algorithm being used, 
    // such as HMAC SHA256 or RSA.
    const header = {
        "kid": "vpaas-magic-cookie-07fabede3674457a84c95fsecretcode/myroom001",
        "alg": "RS256",
        "typ": "JWT"
    }
    const encodedHeaders = btoa(JSON.stringify(header))


    // create the signature part you have to take the encoded header, 
    // the encoded payload, a secret, the algorithm specified in the header, 
    // and sign that.
    const signature = HMACSHA256(`${encodedHeaders}`, "mysecret")


    console.log(`${encodedHeaders}.${signature}`)
</script>

The token that gets generated from code is

eyJraWQiOiJ2cGFhcy1tYWdpYy1jb29raWUtMDdmYWJlZGUzNjc0NDU3YTg0Yzk1ZmE4MGIxNGY1ZDcvVGVzdFJhdW0wMDEiLCJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.not_implemented

And the token that is already generated online is:

eyJraWQiOiJ2cGFhcy1tYWdpYy1jb29raWUtMDdmYWJlZGUzNjc0NDU3YTg0Yzk1ZmE4MGIxNGY1ZDcvMTg1ZDY2LVNBTVBMRV9BUFAiLCJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiJqaXRzaSIsImV4cCI6MTYyMDM4ODU3NiwibmJmIjoxNjIwMzgxMzcxLCJpc3MiOiJjaGF0Iiwicm9vbSI6IioiLCJzdWIiOiJ2cGFhcy1tYWdpYy1jb29raWUtMDdmYWJlZGUzNjc0NDU3YTg0Yzk1ZmE4MGIxNGY1ZDciLCJjb250ZXh0Ijp7ImZlYXR1cmVzIjp7ImxpdmVzdHJlYW1pbmciOmZhbHNlLCJvdXRib3VuZC1jYWxsIjpmYWxzZSwidHJhbnNjcmlwdGlvbiI6ZmFsc2UsInJlY29yZGluZyI6ZmFsc2V9LCJ1c2VyIjp7Im1vZGVyYXRvciI6dHJ1ZSwibmFtZSI6IlRlc3QgVXNlciIsImlkIjoiYXV0aDB8NjA5M2EyYzM3Zjc3MGEwMDcxMGE5YzY5IiwiYXZhdGFyIjoiIiwiZW1haWwiOiJ0ZXN0LnVzZXJAY29tcGFueS5jb20ifX19.aNqg_VLXyafH8Se5rThe6TLz0F2AEnJSmuoZBQ4fXEm1PMx4SBRpelJsrmL76D_jKS5NT-GkuPDVcDgLv6nx9G4ywjws1AH4Lkt0FcJ3eH2OjbFI2WxPzJF_tDJbtPme5LJmGZwEa509v2QD0r-kr31M7FZ83S-kz3O1xKc33FnMJwNlqvgCSN2S0QwF6R5J01zDk41gCk0wGr3DXAmlz0FtCU0qJ5nN9iMUpr5QUY1D-hRApWMhoLPmxkuqnQKLjGwgxU8lh33wq_Laqu7qV57lYrI27er_c42YePwuitWEAAshQU4Ylf2v8sVRv06kQdFPVvICVdsTTI-DLbc3aQ

So basically the first few strings are right but the rest is not generated. I assume it has something to do with mysecret? What exactly is this?

JWT Token

like image 200
Amar.linsila Avatar asked Feb 22 '26 05:02

Amar.linsila


2 Answers

All the instructions are written on this page, https://jwt.io/introduction.

For simplicity, I did not implement HMACSHA256 or use a library to do it. You need to implement this function.

  • If you want to do it from the browser, which doesn't make much sense, How to get HMAC with Crypto Web API.
  • If you want to do it from node (backend), which makes more sense, you can look at this https://www.nodejsera.com/snippets/nodejs/sha256-hmac.html.

const HMACSHA256 = (stringToSign, secret) => "not_implemented"

// The header typically consists of two parts: 
// the type of the token, which is JWT, and the signing algorithm being used, 
// such as HMAC SHA256 or RSA.
const header = {
  "alg": "HS256",
  "typ": "JWT"
}
const encodedHeaders = btoa(JSON.stringify(header))


// The second part of the token is the payload, which contains the claims.
// Claims are statements about an entity (typically, the user) and 
// additional data. There are three types of claims: 
// registered, public, and private claims.
const claims = {
    "role": "admin"
}
const encodedPayload = btoa(JSON.stringify(claims))


// create the signature part you have to take the encoded header, 
// the encoded payload, a secret, the algorithm specified in the header, 
// and sign that.
const signature = HMACSHA256(`${encodedHeaders}.${encodedPayload}`, "mysecret")
const encodedSignature = btoa(signature)

const jwt = `${encodedHeaders}.${encodedPayload}.${encodedSignature}`
console.log({jwt})

Note, that my answer differs from your question in that it is using HS256 instead of RS256. If you want to learn more about the difference you can take a look here: RS256 vs HS256: What's the difference?.

like image 137
The Fool Avatar answered Feb 24 '26 18:02

The Fool


function base64url(source) {
  let encodedSource = CryptoJS.enc.Base64.stringify(source);
  encodedSource = encodedSource.replace(/=+$/, '');
  encodedSource = encodedSource.replace(/\+/g, '-');
  encodedSource = encodedSource.replace(/\//g, '_');
  return encodedSource;
}

function jwtSign(payload, secretOrPrivateKey) {
  const header = { 'alg': 'HS256', 'typ': 'JWT' };
  const stringifiedHeader = CryptoJS.enc.Utf8.parse(JSON.stringify(header));
  const encodedHeader = base64url(stringifiedHeader);
  const stringifiedPayload = CryptoJS.enc.Utf8.parse(JSON.stringify(payload));
  const encodedPayload = base64url(stringifiedPayload);
  const encodedSignature = base64url(CryptoJS.HmacSHA256(encodedHeader + "." + encodedPayload, secretOrPrivateKey));

  return encodedHeader + "." + encodedPayload + "." + encodedSignature;
}

const token = jwtSign({ 'field1': 'test1', 'fileId2': 'test2'}, 'test key');
console.log(token);
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.2.0/crypto-js.min.js"></script>

The above code snippets are working.

like image 21
dabeng Avatar answered Feb 24 '26 19:02

dabeng