Skip to content

Commit 0ca8830

Browse files
author
Divinewill ZERO
committed
[ Feature 🚀 ] Implemented Asymetric encryption algorithm RSA256 when signing and verifying JWT tokens.
1 parent 1f736f8 commit 0ca8830

File tree

13 files changed

+3782
-0
lines changed

13 files changed

+3782
-0
lines changed

‎README.md

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@
9292
| 78. |[How to generate and verify checksum of the given string in Nodejs](#q-how-to-generate-and-verify-checksum-of-the-given-string-in-nodejs)|
9393
| 79. |[What is Callback function in node.js?](#q-what-is-callback-function-in-nodejs)|
9494
| 80. |[What is asynchronous programming in node.js?](#q-what-is-asynchronous-programming-in-nodejs)|
95+
| 81. |[How to implement asymmetric cryptography when signing and verify JSON Web Token (JWT) for authentication in node js?](#q-how-to-implement-asymmetric-cryptography-when-signing-and-verifying-json-web-token-jwt-for-authentication-in-node-js) |
9596

9697
<br/>
9798

@@ -3389,6 +3390,127 @@ The `jwt.sign()` method takes a payload and the secret key defined in `config.js
33893390
<b><a href="#">↥ back to top</a></b>
33903391
</div>
33913392

3393+
## Q. **_How to implement asymmetric cryptography when signing and verify JSON Web Token (JWT) for authentication in node js?_**
3394+
3395+
JSON Web Token (JWT) is an open standard that defines a compact and self-contained way of securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed.
3396+
3397+
There are some advantages of using JWT for authorization:
3398+
3399+
- Purely stateless. No additional server or infra required to store session information.
3400+
- It can be easily shared among services.
3401+
3402+
JSON Web Tokens consist of three parts separated by dots (.), which are:
3403+
3404+
```js
3405+
jwt.sign(payload, secretOrPrivateKey, [options, callback]);
3406+
```
3407+
3408+
- **Header** - Consists of two parts: the type of token (i.e., JWT) and the signing algorithm (i.e., HS512)
3409+
- **Payload** - Contains the claims that provide information about a user who has been authenticated along with other information such as token expiration time.
3410+
- **Signature** - Final part of a token that wraps in the encoded header and payload, along with the algorithm and a secret
3411+
3412+
**Installation**
3413+
3414+
```bash
3415+
npm install jsonwebtoken bcryptjs --save
3416+
```
3417+
3418+
**Ussage**
3419+
3420+
1. `mkdir certs` then run `cd certs`
3421+
3422+
**Inside the certs folder generate public and private key pairs**
3423+
3424+
```bash
3425+
// Private Key
3426+
3427+
>> openssl genrsa -out accessTokenPrivatekey.pem 4096
3428+
3429+
// Public Key
3430+
3431+
>> openssl rsa -pubout -in accessTokenPrivatekey.pem -out accessTokenPublickey.pem
3432+
3433+
```
3434+
3435+
**Example**: AuthController.js
3436+
3437+
```js
3438+
const express = require('express');
3439+
const router = express.Router();
3440+
const bodyParser = require('body-parser');
3441+
const { readFileSync } = require('fs');
3442+
const User = require('../user/User');
3443+
3444+
const jwt = require('jsonwebtoken');
3445+
const bcrypt = require('bcryptjs');
3446+
const config = require('../config');
3447+
3448+
router.use(bodyParser.urlencoded({ extended: false }));
3449+
router.use(bodyParser.json());
3450+
3451+
router.post('/register', function (req, res) {
3452+
const hashedPassword = bcrypt.hashSync(req.body.password, 8);
3453+
3454+
User.create(
3455+
{
3456+
name: req.body.name,
3457+
email: req.body.email,
3458+
password: hashedPassword,
3459+
},
3460+
(err, user) => {
3461+
if (err)
3462+
return res
3463+
.status(500)
3464+
.send('There was a problem registering the user.');
3465+
3466+
//Using the fs module get the private key of the accesstoken you created.
3467+
const ACCESS_TOKEN_PRIV_KEY = readFileSync(
3468+
'./certs/accessTokenPrivateKey.pem',
3469+
'utf8'
3470+
);
3471+
3472+
// create an access token using the private key pair, and specify the algorithm you will use.
3473+
const token = jwt.sign({ id: user._id }, ACCESS_TOKEN_PRIV_KEY, {
3474+
algorithm: 'RS256',
3475+
expiresIn: 86400, // expires in 24 hours
3476+
});
3477+
res.status(200).send({ auth: true, token: token });
3478+
}
3479+
);
3480+
});
3481+
```
3482+
3483+
**To verify a token use the public key**
3484+
3485+
```js
3486+
const ACCESS_TOKEN_PUB_KEY = readFileSync(
3487+
'./certs/accessTokenPubliKey.pem',
3488+
'utf-8'
3489+
);
3490+
3491+
/** Use the Access token Public Key to verify the JWT access token */
3492+
jwt.verify(
3493+
token,
3494+
ACCESS_TOKEN_PUB_KEY,
3495+
{ algorithms: ['RS256'] },
3496+
(err, user) => {
3497+
console.log(err);
3498+
if (err) res.status(403);
3499+
console.log(user);
3500+
}
3501+
);
3502+
```
3503+
3504+
The `jwt.sign()` method takes a payload, private key defined in `./certs/accessTokenPrivateKey.pem` and an object which contains other information about the token, this includes the algorithm `{ algorithm: 'RS256'}`(NB: You can also use `HS256` || `HS384` as algorithm values), that will be used in signing as parameters. It creates a unique string of characters representing the payload. In our case, the payload is an object containing only the id of the user.
3505+
3506+
**Reference:**
3507+
3508+
- **[https://www.npmjs.com/package/jsonwebtoken](https://www.npmjs.com/package/jsonwebtoken)**
3509+
3510+
<div align="right">
3511+
<b><a href="#">↥ back to top</a></b>
3512+
</div>
3513+
33923514
## Q. ***How to build a microservices architecture with Node.js?***
33933515

33943516
**Microservices**
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.env
2+
node_modules
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Express and JSON Web Token Authentication Using Asymetric Encryption Algorithm (RSA256)
2+
3+
When creating jsonwebtoken rather than signing and verifying tokens with a secret key use Asymetric encryption instead using pubic and private key pairs
4+
5+
<br>
6+
7+
- `cd` into jwt-authentication folder in your terminal run `mkdir certs`, then type `cd certs`.
8+
- Generate a public and private key for both access and refresh tokens:
9+
10+
```bash
11+
/** To generate a public and private key for access tokens */
12+
13+
// Private Key
14+
>> openssl genrsa -out accessTokenPrivatekey.pem 4096
15+
16+
// Public Key
17+
>> openssl rsa -pubout -in accessTokenPrivatekey.pem -out accessTokenPublickey.pem
18+
```
19+
20+
```bash
21+
/** To generate a public and private key for refresh tokens */
22+
23+
// Private Key
24+
>> openssl genrsa -out refreshTokenPrivatekey.pem 4096
25+
26+
// Public Key
27+
>> openssl rsa -pubout -in refreshTokenPrivatekey.pem -out refreshTokenPublickey.pem
28+
```
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
require('dotenv').config();
2+
3+
const express = require('express');
4+
const app = express();
5+
const jwt = require('jsonwebtoken');
6+
const { readFileSync } = require('fs');
7+
const { promisify } = require('util');
8+
9+
app.use(express.json());
10+
11+
let refreshTokens = [];
12+
13+
app.post('/token', async (req, res, next) => {
14+
try {
15+
const refreshToken = req.body.token;
16+
if (refreshToken === null)
17+
res.sendStatus(401).json({ error: 'Provide a token' });
18+
console.log(refreshTokens);
19+
if (!refreshTokens.includes(refreshToken)) return res.sendStatus(403);
20+
21+
const REFRESH_TOKEN_PUB_KEY = readFileSync(
22+
'./certs/refreshTokenPubliKey.pem',
23+
'utf8'
24+
);
25+
26+
/** use the refresh Token public key to verify the JWT refresh token that was signed with the private key */
27+
jwt.verify(
28+
refreshToken,
29+
REFRESH_TOKEN_PUB_KEY,
30+
{
31+
algorithms: ['RS256'],
32+
},
33+
(err, user) => {
34+
if (err) res.sendStatus(403).json({ message: err.message });
35+
const accessToken = generateAccessToken(user.name);
36+
res.json({ accessToken: accessToken });
37+
}
38+
);
39+
} catch (error) {
40+
console.log(error.message);
41+
}
42+
});
43+
44+
app.delete('/logout', (req, res) => {
45+
refreshTokens = refreshTokens.filter((token) => token !== req.body.token);
46+
res.sendStatus(204);
47+
});
48+
49+
app.post('/login', async (req, res) => {
50+
try {
51+
// Authenticate User
52+
const username = req.body.username;
53+
const user = { name: username };
54+
55+
const REFRESH_TOKEN_PRIV_KEY = readFileSync(
56+
'./certs/refreshTokenPrivateKey.pem',
57+
'utf8'
58+
);
59+
60+
const accessToken = generateAccessToken(user);
61+
62+
/** Use the Refresh Token Private Key to sign a JWT refresh token*/
63+
const refreshToken = jwt.sign({ user }, REFRESH_TOKEN_PRIV_KEY, {
64+
algorithm: 'RS256',
65+
expiresIn: '60s',
66+
});
67+
68+
refreshTokens.push(refreshToken);
69+
console.log(refreshTokens);
70+
res.json({ accessToken: accessToken, refreshToken: refreshToken });
71+
} catch (err) {
72+
console.log(err.message);
73+
}
74+
});
75+
76+
function generateAccessToken(user) {
77+
const ACCESS_TOKEN_PRIV_KEY = readFileSync(
78+
'./certs/accessTokenPrivateKey.pem',
79+
'utf8'
80+
);
81+
82+
/** Use the Access Token Private Key to sign a JWT access token*/
83+
return jwt.sign({ user }, ACCESS_TOKEN_PRIV_KEY, {
84+
algorithm: 'RS256',
85+
expiresIn: '1hr',
86+
});
87+
}
88+
89+
app.listen(4000, () => console.log(`App is running at http://localhost:4000`));
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
-----BEGIN RSA PRIVATE KEY-----
2+
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
51+
-----END RSA PRIVATE KEY-----
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
-----BEGIN PUBLIC KEY-----
2+
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEArt44dqQGQIQpXm3GcQao
3+
yeRL8mIfN3ob8kyNwZfSPSLnDV29cYfRo6WG7jEnV5ehFwGD5KD0LEP4SlUbs5Uj
4+
fLstl58B9vVrdlo/Q7oevkcLNionMjFLURjBtLjDZztCpcpJBIB1cFR45w77k/hE
5+
ozMKwNutZP5Jm6QtGMFnc3jGlcY/tar3/AP779SquclE0v6H7mLbxZidHyHICd39
6+
5Xoe4Q648ERds5bfYWorUpBLmdzrIUt2M6OV/YITHr/cF8TpDI/6KMjZkboUYm+w
7+
/V8uO/Gcz2KUkQqP5jzCjVoRvT0y/HQ4ZtHnX7P6qZ9ApgyQrrWZIYS1bw6odBJB
8+
da+C0kbSuCHnTE+XdIcep/1HKAX75Z9Z9XD6oyjxO82QrBAZ27e3Tk0f/lzIppGH
9+
WmihzjVXzQoU1/YDy/K9VPl11ze4Z/XPwu3P90B9e/bUhIezDHLYiGjGdOELJ4V+
10+
f+xtnuP87glFYWQ3btJesnkp4UpWuJfMvpLwgZnzyiglwGKj+/d7SqeF8D5bhdi/
11+
ewRo96lqL4/UzDjg0bGNCy7wNKaP6LQfhkeSFWyw4/u73n1Xot9Tvbf5/sQia1tl
12+
whZWKzcWdEXnZb/dBK3bT9XYRcgstXwUODkc7cpJ20iIM1rLBpFu7SqQLuEIDVuq
13+
nIdcNg52P8GpQ2Bnicq1ZyMCAwEAAQ==
14+
-----END PUBLIC KEY-----
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
-----BEGIN RSA PRIVATE KEY-----
2+
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
51+
-----END RSA PRIVATE KEY-----
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
-----BEGIN PUBLIC KEY-----
2+
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAqzeDd8smeUebrYfgDqva
3+
wROpzP5Pe/xJo97UHAYj8Fg7K1CIVC3fNbUxPT6BrRFyb/TOJwRw9lvkfffRUoW/
4+
skheEaZf7db+6rgk1OTWsULzPLbo/AjIPgKRepzWj5STq56ZEbnpdrYmzcWtIlUz
5+
9Op/sPdxpUvbioSH0x9gHVU8Posolv64h1kehajeC/QN1YUXxKq/IF/p383/RZOU
6+
LV+7IkWOFsrKxZ5KJ6oNsqvKoa0BG0zVZ1MX7AbsRCm6FM4ddJMaHFAiSchOFOoB
7+
7heqN4Mi/iVJWq084Irc+N64OPB62A9OKWsGmTcm9NtZLa3aicI+7LqS8oMVwUM9
8+
ZeOYGbMXVrOHxkPFbI8JM7uz4pg3sYazyG7nir9bsAXqTDs0l1v0DXhRoAKEV4dJ
9+
TJE9IHpiJGeIi1ykBbXXV0oW2meE9vHMIHiT92C+w33zA7uuZjDk6s9yGWc8LBAd
10+
lsD/YfIr5U6A1Ma3weHzcyAcHBtZO+1Ao/nZvTsH2EWdZx35Xit2+l6kx0MJs3Db
11+
2CIoRoJpvvoEv1ns5jHMYscgXt07YSwAWKOSSA9aYPQxfa/OBT9qWaDBNK0esJJu
12+
n03LHf30dT/gJI9MkB0Cn/c/yuaCw04aDKYVk+AHIXlKLcjTr7M8l3R5J8IlRgT/
13+
/WAw9Qk8OjGW6tBxs8kY8oECAwEAAQ==
14+
-----END PUBLIC KEY-----
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
ACCESS_TOKEN_SECRET=some_secret_key
2+
3+
REFRESH_TOKEN_SECRET=some_secret_key

0 commit comments

Comments
 (0)