{"id":920,"date":"2022-01-23T00:15:40","date_gmt":"2022-01-22T23:15:40","guid":{"rendered":"https:\/\/nguenkam.com\/blog\/?p=920"},"modified":"2022-01-23T00:15:40","modified_gmt":"2022-01-22T23:15:40","slug":"nodejs-jwt-authentication","status":"publish","type":"post","link":"https:\/\/nguenkam.com\/blog\/index.php\/2022\/01\/23\/nodejs-jwt-authentication\/","title":{"rendered":"NodeJS &#8211; JWT Authentication"},"content":{"rendered":"\n<p><a rel=\"noreferrer noopener\" href=\"https:\/\/jwt.io\/\" target=\"_blank\">JSON Web Tokens<\/a>\u00a0(JWTs) supports authorization and information exchange.<\/p>\n\n\n\n<p>One common use case is for allowing clients to preserve their session information after logging in. By storing the session information locally and passing it to the server for authentication when making requests, the server can trust that the client is a registered user.<\/p>\n\n\n\n<p>In this article, we will learn about the applications of JWTs in a server-client relationship using Node.js and vanilla JavaScript.<\/p>\n\n\n\n<h4><span class=\"has-inline-color has-vivid-cyan-blue-color\">Step 1 \u2014 Generating a Token<\/span><\/h4>\n\n\n\n<p><code>jsonwebtoken<\/code>&nbsp;is an implementation of JSON Web Tokens.<\/p>\n\n\n\n<p>You can add it to your JavaScript project by running the following command in your terminal:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm install jsonwebtoken<\/code><\/pre>\n\n\n\n<p>And import it into your files like so:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const jwt = require('jsonwebtoken');<\/code><\/pre>\n\n\n\n<p>To sign a token, you will need to have 3 pieces of information:<\/p>\n\n\n\n<ol><li>The token secret<\/li><li>The piece of data to hash in the token<\/li><li>The token expire time<\/li><\/ol>\n\n\n\n<p>The\u00a0<em><strong>token secret<\/strong><\/em>\u00a0is a long random string used to encrypt and decrypt the data.<\/p>\n\n\n\n<p>To generate this secret and make it more complicated to be hacked, one option is to use Node.js\u2019s built-in\u00a0<code>crypto<\/code>\u00a0library, like so:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>> require('crypto').randomBytes(64).toString('hex')\r\n\/\/'09f26e402586e2faa8da4c98a35f1b20d6b033c6097befa8be3486a829587fe2f90a832bd3ff9d42710'<\/code><\/pre>\n\n\n\n<p><em><span class=\"has-inline-color has-vivid-red-color\"><strong>PS:<\/strong><\/span><\/em> <em>Be careful! If your\u00a0<code>secret<\/code>\u00a0is simple, the token verification process will be much easier to break by an unauthorized intruder.<\/em><\/p>\n\n\n\n<p>Now, store this secret in your project\u2019s\u00a0<em><strong><code>.env<\/code>\u00a0<\/strong>file<\/em>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>TOKEN_SECRET=09f26e402586e2faa8da4c98a35f1b20d6b033c60...<\/code><\/pre>\n\n\n\n<p>To bring this token into a Node.js file and to use it, you have to use\u00a0<code>dotenv<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm install dotenv\r<\/code><\/pre>\n\n\n\n<p>And import it into your files like so:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const dotenv = require('dotenv');\r\n\r\n\/\/ get config vars\r\ndotenv.config();\r\n\r\n\/\/ access config var\r\nprocess.env.TOKEN_SECRET;<\/code><\/pre>\n\n\n\n<p>The&nbsp;<em>piece of data<\/em>&nbsp;that you hash in your token can be something either a user ID or username or a much more complex object. In either case, it should be an&nbsp;<em>identifier<\/em>&nbsp;for a&nbsp;<em>specific<\/em>&nbsp;user.<\/p>\n\n\n\n<p>The&nbsp;<em>token expire time<\/em>&nbsp;is a string, such as 1800 seconds (30 minutes), that details how long until the token will be invalid.<\/p>\n\n\n\n<p>Here\u2019s an example of a function for signing tokens:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>function generateAccessToken(username) {\r\n  return jwt.sign( { username: username }, \n                   process.env.TOKEN_SECRET, \n                   { expiresIn: '1800s' }\n                );\r\n}<\/code><\/pre>\n\n\n\n<p>This can be sent back from a request to sign in or log in a user:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>app.post('\/api\/createNewUser', (req, res) => {\r\n  \/\/ ...\r\n\r\n  const token = generateAccessToken({ username: req.body.username });\r\n  res.json(token);\r\n\r\n  \/\/ ...\r\n});<\/code><\/pre>\n\n\n\n<p>This example takes the\u00a0<code>username<\/code>\u00a0value from the\u00a0<code>req<\/code>\u00a0(<em>request<\/em>). And provides the token as the\u00a0<code>res<\/code>\u00a0(<em>response<\/em>).<\/p>\n\n\n\n<p>That concludes how\u00a0<code>jsonwebtoken<\/code>,\u00a0<code>crypto<\/code>, and\u00a0<code>dotenv<\/code>\u00a0can be used to generate a JWT.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4><span class=\"has-inline-color has-vivid-cyan-blue-color\">Step 2 \u2014 Authenticating a Token<\/span><\/h4>\n\n\n\n<p>There are many ways to go about implementing a JWT authentication system in an&nbsp;<a href=\"https:\/\/expressjs.com\/\">Express.js<\/a>&nbsp;application.<\/p>\n\n\n\n<p>One approach is to use the\u00a0<a href=\"#\" data-type=\"URL\">middleware<\/a>\u00a0functionality in Express.js.<\/p>\n\n\n\n<p>How it works is when a request is made to a specific route, you can have the&nbsp;<code>(req, res)<\/code>&nbsp;variables sent to an intermediary function before the one specified in the&nbsp;<code>app.get((req, res) =&gt; {})<\/code>.<\/p>\n\n\n\n<p>The middleware is a function that takes parameters of&nbsp;<code>(req, res, next)<\/code>.<\/p>\n\n\n\n<ul><li>The&nbsp;<code>req<\/code>&nbsp;is the sent request (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Hypertext_Transfer_Protocol\">GET, POST, DELETE, PUT, etc.<\/a>).<\/li><li>The&nbsp;<code>res<\/code>&nbsp;is the response that can be sent back to the user in a multitude of ways (<code>res.sendStatus(200)<\/code>,&nbsp;<code>res.json()<\/code>, etc.).<\/li><li>The&nbsp;<code>next<\/code>&nbsp;is a function that can be called to move the execution past the piece of middleware and into the actual&nbsp;<code>app.get<\/code>&nbsp;server response.<\/li><\/ul>\n\n\n\n<p>Here is an example middleware function for authentication:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const jwt = require('jsonwebtoken');\r\n\r\nfunction authenticateToken(req, res, next) {\r\n  const authHeader = req.headers&#91;'authorization']\r\n  const token = authHeader &amp;&amp; authHeader.split(' ')&#91;1]\r\n\r\n  if (token == null) return res.sendStatus(401)\r\n\r\n  jwt.verify(token, process.env.TOKEN_SECRET as string, (err: any, user: any) => {\r\n    console.log(err)\r\n\r\n    if (err) return res.sendStatus(403)\r\n\r\n    req.user = user\r\n\r\n    next()\r\n  })\r\n}<\/code><\/pre>\n\n\n\n<p>An example request using this middleware function would resemble something like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>GET https:\/\/example.com:4000\/api\/userOrders\r\nAuthorization: Bearer JWT_ACCESS_TOKEN<\/code><\/pre>\n\n\n\n<p>And an example of a request that would use that piece of middleware (in NodeJs)  would resemble something like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>app.get('\/api\/userOrders', authenticateToken, (req, res) => {\r\n  \/\/ executes after authenticateToken\r\n  \/\/ ...\r\n})<\/code><\/pre>\n\n\n\n<p>This code will authenticate the token provided by the client. If it is valid, it can proceed to the request. If it is not valid, it can be handled as an error.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4><span class=\"has-inline-color has-vivid-cyan-blue-color\">Step 3 \u2014 Handling Client-Side Tokens<\/span><\/h4>\n\n\n\n<p>When the client receives the token, they often want to store it for gathering user information in future requests.<\/p>\n\n\n\n<p>The most popular manner for storing auth tokens is in an&nbsp;<code>HttpOnly<\/code>&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/HTTP_cookie\">cookie<\/a>.<\/p>\n\n\n\n<p>Here\u2019s an implementation for storing a cookie using client-side JavaScript code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ get token from fetch request\r\nconst token = await res.json();\r\n\r\n\/\/ set token in cookie\r\ndocument.cookie = `token=${token}`<\/code><\/pre>\n\n\n\n<p>This approach stores the response locally where they can be referenced for future requests to the server.<\/p>\n\n\n\n<p>That concludes the flow of requesting a token, generating a token, receiving a token, passing a token with new requests, and verifying a token.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h5>Reference:<\/h5>\n\n\n\n<p><a href=\"https:\/\/www.digitalocean.com\/\">https:\/\/www.digitalocean.com\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>JSON Web Tokens\u00a0(JWTs) supports authorization and information exchange. One common use case is for allowing clients to preserve their session information after logging in. By storing the session information locally and passing it to the server for authentication when making requests, the server can trust that the client is a registered user. In this article, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1603,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[145],"tags":[233,230,232,231],"_links":{"self":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/920"}],"collection":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=920"}],"version-history":[{"count":2,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/920\/revisions"}],"predecessor-version":[{"id":1604,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/920\/revisions\/1604"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/media\/1603"}],"wp:attachment":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=920"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=920"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=920"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}