JSON web token (JWT) are a really good opportunity to create secure login workflows without storing tons of access tokens in your database. But as good as it might sound in the first moment they have a huge problem. After giving them to a user, you can't really control, if someone will copy them to another machine.
This makes it easy for everyone to just copy a JSON web token out of the Local Storage and place it somewhere else.
One of the first ideas you may have, if you want to solve this problem is to bind them to the clients ip so nobody from outside can use the token, but since we are speaking of IP scarcity and things like DS-Lite, this isn't a really good solution.
The only really good solution for this would be to give each browser a unique ID, which only can be manipulated hardly like the MAC address.
Sadly nowadays browsers doesn't provide built in endpoint for this, so we have to built something around the existing APIs.
When you search around the internet for a while you will soon find some projects like AmIUnique, which are using parameters like your computers User Agent or the way of rendering text to distinguish between devices and browsers. When you use some of these indetifiers you can create a unique id for any device and browser as long as there aren't any updates to your system. But because in our case JWTs only need to be valid for some hours or days this should work fine.
To show you how to implement this into your apps I will create a sample react app and use the uniquebrowserid package for creating the unique IDs.
After you initialize your app, you can install the package with
npm install uniquebrowserid, open the
App.js file and add the following code:
After saving the file and running
npm run startyou should see your unique browser ID in the app.
To bind this into your JSON Web Tokens, you just need to send the result of the
new UID().completeID()function to your backend.
If you want to learn more about the implementation of unique browser IDs into your app, you can visit the packages website at: https://www.npmjs.com/package/uniquebrowserid. There you also find, how to create one time unique IDs.