Quick Introduction to JWT using Javascript
June 20, 2019
JWT(JSON Web Token) is being used a lot to authenticate SPAs(Single Page Applications) but before we get started, we should know what a JWT is. I’ve put a short summary below, but if you need more information, visit the official JWT website.
JSON Web Token (JWT) is an open standard that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret or a public/private key…
The process of authentication and validation is very simple, let’s see how it happens:
- The SPA sends a login request with the user credentials
- The backend verifies that the credentials are valid
- If the credentials are valid, the backend will generate a new token using a payload containing some user identifier(such as id, or email) and a secret.
- The backend sends the token to the SPA.
- The SPA stores the token.
- The SPA uses the token as an authorization header in an HTTP request.
- The backend checks the token.
- If the token is valid, the backend returns the requested data.
Now that we are understanding the process we can turn it into code.
Code sample
Backend - Logging in and generating the token
const jwt = require('jsonwebtoken');
const signIn = async (req, res) => {
const { email, password } = req.params
try {
const user = await doLogin(email, password);
const token = jwt.sign({ userId: user.id }, 'your-secret');
return res.json({
token
})
} catch(error) {
...
}
}
SPA - Sending the sign in request and getting the token
import axios from 'axios'
import Cookies from 'js-cookie'
const signIn = async (email, password) => {
try {
const credentials = await axios.post('/signIn', { email, password })
Cookies.set('credentials', credentials) } catch(error) {
...
}
}
SPA - Sending a request to get some private data
import axios from 'axios'
import Cookies from 'js-cookie'
const getBooks = (email, password) => {
try {
const credentials = Cookies.getJSON('credentials')
if(!credentials) {...}
return axios.post('/books', null, {
headers: {
authorization: credentials.token }
})
} catch(error) {
...
}
}
Backend - Checking the request
const jwt = require('jsonwebtoken');
const books = async (req, res) => {
try {
const token = req.headers.authorization const { userId } = jwt.verify(token, 'your-secret');
return res.json(
Books
.where({
user_id: userId
})
.all()
)
} catch(error) {
...
}
}
Security concerns
- Use your jwt secret as an env variable like
process.env.JWT_SECRET
. - Use the expiration time on tokens and cookies. You do not want to have a leaked token living forever.
- Do not put sensitive data inside the payload because the token can be easily decoded but no one is able to create a valid token without the secret.
- Use a strong secret. You can use some app for this like https://randomkeygen.com/.
Example with 1 day expiration:
// Backend
jwt.sign(
{ userId: user.id },
'your-secret',
{ expiresIn: '1d' } );
// SPA
Cookies.set(
'credentials',
credentials,
{ expires: 1 } )
I hope you have enjoyed this article and it has been useful to you. Thanks for reading!
Written by Bruno Quaresma
Sr. Front-end Developer at Fauna
Twitter