Using JSON Web Tokens (JWT) with Wappler — Part 1
This first part will cover signing information with a JWT in a Wappler NodeJS environment.
Why JWT?
Wappler has built-in security providers to authenticate users and create roles in a MySQL database.
In some cases, you might want to authenticate external API requests with something more secure than basic auth, connect multiple applications and exchange signed information between these, or authenticate your users with a NoSQL database.
JSON web tokens are an excellent solution for the above. This first part will cover signing information with a JWT in a Wappler NodeJS environment.
Multiple algorithms are available for generating JWT tokens like HMAC, RSA, and ECDSA. We will use RS256 in this example since it lets us use a private and public key pair for signing our payload.
Generating a Private and Public Key
We will use the private key to sign the token and the public key to verify the token. Your private key should NEVER leave the system it was generated on. So we will create the key pair on your server or local system, convert it to base64, and store it as an ENV value.
You can create the key pair using either ssh-keygen or OpenSSL.
You can check if you have OpenSSL on your system by running openssl version
in your terminal.
To generate your key pair with OpenSSL, go to the root of your Wappler project and run:openssl genrsa -out private.pem 2048
openssl rsa -in private.pem -pubout -out public.pem
If you don't have OpenSSL on your system, then you can use ssh-keygen by running:ssh-keygen -t rsa -P "" -b 4096 -m PEM -f jwtRS256.key
ssh-keygen -e -m PEM -f jwtRS256.key > jwtRS256.key.pub
Next, base64 encode both keys. There are multiple ways to do this, depending on your system. I'm going to use OpenSSL for this example:openssl base64 -in private.pem -out privatekey
openssl base64 -in public.pem -out publickey
You can display your base 64 encoded keys by running:cat privatekey
cat publickey
Copy the private key to your clipboard and open your Wappler project. We will store the base64 encoded private key in our project's ENV.
Go to Workflows -> Globals, add two text variables under $ENV, and save your Globals. I will name them PRIVATEKEY and PUBLICKEY.
We also need to add the keys to the ENV under server connect settings. So go to server connect -> settings -> ENV and add the variables we created before.
Copy and paste the base64 encoded private and public keys to the corresponding ENV rows.
Signing a JWT
Now we can finally build our workflow to sign a JWT token.
Go to Workflows and create a new API workflow. Add two ENV variables under Input. One for your private key and one for the public key. The names need to match the names of the ENV values we added under server connect.
We will use these values to sign the JWT, so go to Execute and add the JWT Sign action. Your workflow should look like this:
You mustn't store sensitive information in a JWT. Everybody who has access to the signed token can read the content. We sign the token with our private key and verify it with the public key. So while the content is readable by anybody who has access, it can't be modified, or the verification will fail.
I assume you want to use the token to authenticate an API request or a user login. So we are going to store the user_id
in our token. The user_id
will allow us to authenticate and look up the user when a request hits our endpoint.
Fill out the JWT Sign Properties:
- Issuer (string): The issuer, in this case, is your application, so you can define any value.
- Algorithm: We use RS256 because it allows us to sign the token with a key.
- Subject(string): That's an excellent place to store the
user_id
. You can look up the id from your database, but I will use a static example to keep it simple. - Audience(string): Define the audience.
- JWT ID(string): This needs to be a unique id. You can use the built-in UUID function in Wappler.
- Expires in(string): The expiration date for your token. If you don't want the token to expire, you can add 9999 years.
- Key: The decoded private key from your ENV.
You can add additional information you want to store in the token as claims.
Let's output our signed token by adding a Set Value step to our workflow. Use the output of your JWT sign action as the value and check the output box.
Save and run your workflow. You should see the signed token in your browser.
Voilà, you signed your first JWT token!
We can check the content by visiting jwt.io.
Copy and paste your token to the encoded input.
This will display the decoded content:
As mentioned, everybody with access to the token can decode it, but we can verify that the content wasn't changed with our public key.
Part 2 will follow soon and cover the verification of a JSON Web Token.
Thank you for reading until here; see you next time.