How to increase the security of your application — Rails and React
So, I graduated from Flatiron School, I am finally a Software Engineer, now, trying to improve my skills and learning new things (that forever learning thing really got into my mind!).
While working on those personal goals, I decide to write a couple articles about one thing that really got my attention during my final project during my journey as a Flatiron student.
My final app handles user’s information like name, email, phone number, address, items the user has on the website, all the needed information to exchange items between users.
If you want to check my app (Let-Me-Go!), here is the link:
So, security and was a key point for me while developing the app!
Are you worried about your applications and how safe the users are using your platform? In this blog, I am going to explain a solution I came up with, hopefully it can help.
The app was created using Rails for the back-end and React for the front-end, so I am assuming that if you are reading this, you already know the basics about back/front-end and how to connect both of them, as we will see fetches, routes, controllers, parameters and methods.
We know JWT is one way of handle logins and validations of the user, checking if the data sent to the server is authenticated or not, but what if the user leaves the application without logoff and not come back to the website in hours, days or even months?
Your token is going to live in the user’s browser forever, or at least until he (maybe) decides to clean up the information hold in the browser.
What if someone access this client with your token there and uses it to access the user’s data in your server? Your server will check if the token is valid (it will be) and then will give this “hacker” access to your user data.
“But I didn’t do anything wrong, I checked the token, it’s valid, what else can I do?”
I am going to talk about how to increase the security of React applications using JWT (yes, nothing new until here) and how to check, renew and issue a new valid token that lasts 30 min (or how long you define) so if the users leave the website to do anything else, forgets to come back and logoff, he will be logged off for his own safety.
How do I login a user?
There are a lot of ways of doing that, but the one I like is:
You send a request from the front end, after the user’s input username and password (userData):
It’s been sent in an object, that contains a key user and the value is the userData itself.
You can define your routes, in my case, I am making a POST request to “/login”:
This will go to auth controller and hit the login method:
Don’t forget to skip the authorized action for login, it makes no sense to ask for an authorization if you are trying to get one, right?
As I mentioned before, in this case I’m just using username and password:
First, we find the user based on the data that was sent (username), than we check if the password is correct in the method @user.authenticate (using the magic BCrypt gives us).
After that, if the user is authenticated, we have the interesting part! To issue a token, we use the method token_with_user_id_and_time(@user), that takes in the @user we just found.
But what is this method? This method put an additional info in the token, a timestamp.
It catches the exact time we are issuing the token with Time.now and convert it into integer with .to_i, that converts “2020–09–04 16:55:21 +0100” into “1599234911”.
Then, encode_token with the user ID and this issued_date, the timestamp.
Back to the response of the method login, we send the jwt: @token with this “dated” token.
Now, every time the user makes a request, or something that interacts with the database, we check if the token is still valid based on the user’s data and if it’s still in the time window we define, if is not, the user is not authorized, if it’s valid, then we issue a new token and send this brand new token (with a new window of time) to the user, as a JSON response to the client request.
I’ll show how to validate and check the token in the front-end, as well as how to handle the login and store the user data with localStorage variable in the second part of this article.
See you next week!