Search code examples
javascriptnode.jstypescriptjwtjose

JWT signature for both node.js and browsers


I want to authenticate Salesforce's OAuth 2.0 JWT Bearer Flow with both node.js and Browser.
I have created a public key and a private key on Windows with the following command.

openssl req -x509 -sha256 -nodes -days 36500 -newkey rsa:2048 -keyout salesforce.key -out salesforce.crt

I tried JWT Sign with the following Typescript code using panva/jose

import { SignJWT } from "jose";
import serverKey from "../../../credential/salesforce.key?raw";

export async function jwtSign() {
    const assertion = await new SignJWT({ prn: import.meta.env.VITE_SF_MAIL })
        .setProtectedHeader({ alg: 'RS256' })
        .setIssuer(import.meta.env.VITE_SF_CLIENT_ID)
        .setAudience(import.meta.env.VITE_SF_AUDIENCE)
        .setExpirationTime('15h')
        .sign(new TextEncoder().encode(serverKey));
    return assertion;
}

But I get the following error.

Key must be one of type KeyObject or CryptoKey. Received an instance of Uint8Array
TypeError: Key must be one of type KeyObject or CryptoKey. Received an instance of Uint8Array
    at asymmetricTypeCheck (D:\repository\PROJECT\node_modules\jose\dist\node\cjs\lib\check_key_type.js:17:15)
    at checkKeyType (D:\repository\PROJECT\node_modules\jose\dist\node\cjs\lib\check_key_type.js:44:9)
    at FlattenedSign.sign (D:\repository\PROJECT\node_modules\jose\dist\node\cjs\jws\flattened\sign.js:55:41)
    at CompactSign.sign (D:\repository\PROJECT\node_modules\jose\dist\node\cjs\jws\compact\sign.js:14:43)
    at SignJWT.sign (D:\repository\PROJECT\node_modules\jose\dist\node\cjs\jwt\sign.js:22:20)
    at Module.jwtSign (D:/repository/PROJECT/src/lib/app/service/func.ts:10:9)
    at load (D:/repository/PROJECT/src/routes/+page.server.ts:8:10)
    at load_server_data (file:///D:/repository/PROJECT/node_modules/@sveltejs/kit/src/runtime/server/page/load_data.js:32:41)
    at file:///D:/repository/PROJECT/node_modules/@sveltejs/kit/src/runtime/server/page/index.js:168:19
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

How can i fix this error?
Or is there any other way to implement it?


Solution

  • replace new TextEncoder().encode(serverKey) with await importPKCS8(serverKey, 'RS256')

    importPKCS8 (docs) is the function used to import asymmetric private keys in PKCS8 format.