Learning JWT Part 8 - Signup an user with JWT === ![](https://i.imgur.com/qFSfCl5.png) --- ###### tags: `JWT` ## Install JWT - `npm i jsonwebtoken` ### Create token - First we need to import `jwt` in `authController.js`; - Add secret key inside `.env`, it has to be a `string`; ```javascript= // authController.js const env = require("dotenv").config(); const jwt = require("jsonwebtoken"); // create token // Define max expired time 3 days const maxAge = 3 * 24 * 60 * 60; const createToken = (id) => { return jwt.sign({id}, process.env.JWT_SECRET, { expiresIn: maxAge }); }; // Fire create token function onece user signing up. module.exports.signup_post = async (req, res) => { const { email, password } = req.body; try{ const user = await User.create({ email, password }); const token = createToken(user._id); res.cookie("jwt", token, { httpOnly: true, maxAge: maxAge * 1000 }); res.status(201).json({ user: user._id }); } catch (error) { const errors = handleError(error); res.status(400).json({ errors }); } } ``` user._id refers to the id created in db. ![](https://i.imgur.com/0sS6yCc.png) Now, let's signup a new user and open console, click application to see if jwt has created. ![](https://i.imgur.com/GSJuALC.png) --- ## Check if there's an error or not and update UI When we submit the form, we will get response from server, if we receive an error, we want to update our UI to inform user. Check the response, it's either user id or an error. ```javascript= module.exports.signup_post = async (req, res) => { const { email, password } = req.body; try { const user = await User.create({ email, password }); const token = createToken(user._id); res.cookie("jwt", token, { httpOnly: true, maxAge: maxAge * 1000 }); res.status(201).json({ user: user._id }); } catch (error) { const errors = handleError(error); res.status(400).json({ errors }); } }; ``` ```javascript= // signup.ejs <%- include('partials/header'); -%> <form action="/signup"> <h2>Sign up</h2> <label for="email">Email</label> <input type="text" name="email" required /> <div class="email error"></div> <label for="password">Password</label> <input type="password" name="password" required /> <div class="password error"></div> <button>Sign up</button> </form> <script> const form = document.querySelector('form'); const emailError = document.querySelector('.email.error'); const passwordError = document.querySelector('.password.error'); form.addEventListener('submit', async (e) => { e.preventDefault(); const email = form.email.value; const password = form.password.value; try { const res = await fetch('/signup', { method: 'POST', body: JSON.stringify({ email, password }), headers: { 'Content-Type': 'application/json' } }).then(res => res.json()); // Check the res console.log(res); } catch (err) { console.log(err); } }) </script> <%- include('partials/footer'); -%> ``` Let's try to signup an user with invalid email. ![](https://i.imgur.com/FSLOtsQ.png) ![](https://i.imgur.com/RVzsBt9.png) Try with invalid password. ![](https://i.imgur.com/lw0W9Hm.png) ![](https://i.imgur.com/SZ4h4OX.png) Now we can see the content of `res`, it is an object contains `errors` and inside `errors`, there're `email` and `password`, we can access its message and update UI. ```javascript= // signup.ejs ... try { const res = await fetch('/signup', { method: 'POST', body: JSON.stringify({ email, password }), headers: { 'Content-Type': 'application/json' } }).then(res => res.json()); if (res.errors) { emailError.textContent = res.errors.email; password.textContent = res.errors.password; } } catch (err) { console.log(err); } ... ``` Let's try to signup with invalid email and password. We have successfully show the error message to user. ![](https://i.imgur.com/Rn6Dplf.png) It's not a good user experience as the error message should be gone when user makes amendment. ```javascript= // signup.ejs form.addEventListener('submit', async (e) => { e.preventDefault(); const email = form.email.value; const password = form.password.value; // Reset error value emailError.textContent = ''; passwordError.textContent = ''; try { const res = await fetch('/signup', { method: 'POST', body: JSON.stringify({ email, password }), headers: { 'Content-Type': 'application/json' } }).then(res => res.json()); if(res.errors) { emailError.textContent = res.errors.email; passwordError.textContent = res.errors.password; } } catch (err) { console.log(err); } }) ``` ![](https://i.imgur.com/HW2eXXV.gif) --- ## Signup and redirect to homepage We can check if user exists in `res`, if exists, then redirect to homepage. ```javascript= // signup.ejs form.addEventListener('submit', async (e) => { e.preventDefault(); const email = form.email.value; const password = form.password.value; // Reset error value emailError.textContent = ''; passwordError.textContent = ''; try { const res = await fetch('/signup', { method: 'POST', body: JSON.stringify({ email, password }), headers: { 'Content-Type': 'application/json' } }).then(res => res.json()); if(res.errors) { emailError.textContent = res.errors.email; passwordError.textContent = res.errors.password; } // Redirect user to homepage if (res.user) { location.assign('/'); } } catch (err) { console.log(err); } }) ```