While building my website I decided to use JWT for the authentication feature. In the front-end I have React and in back-end Express server with Postgres database.
Right now when user tries to log in, I verify his credentials against the database and then issue a token, which then is stored in http-only cookie in the browser.
However right now I'm struggling with some front-end problems. I need to have some sort of 'CurrentUser' object on the client side. The problem is that I can't decode token and retrieve data from it using React, since it is http-only. I could additionally send user credentials along with the token and then store them in local/session storage, but that doesn't seem secure to me.
Perhaps I misunderstand something about the applications of JWT, if so, could you please correct me and give some advice about how I should handle my authentication ?
Related
I'm working on a website where the user needs to log in to view the content. I'm working with react for the frontend and i'm using node to develop the API. I'm trying to protect my pages with a json web token, this way once the user logs into, the server gives a jwt which the frontend asks for to let the user to continue navigating or otherwise redirecting him to the login.
I know the server needs to verify the token, and i know i can create a middleware and implementing it to my API routes to achieve this. But my question is, if in the page i want to display i don't need to call any API route how can i verify the token?
I mean, should i create a route only to verify the token? or there is better way to do it?
Any suggestion or code example is welcome.
I suggest to use backend for token verification it is easier to manage in long run and safer. For example , if you use hmacsha256 signature , you have to leak your private key to client side for token verification. For client side identity verification, i suggest work with server side rendering instead to limit access to the protected part of website.
Let's say I'm trying to build a web application using Vue.js where an end user uses a form to subscribe to a newsletter.
The frontend is a Vue app, the backend is a PHP REST API.
The API requires Basic Auth authentication.
In the frontend I'm calling the API using axios:
axios
.post('localhost/api/v1/subscriber.php', {
// I know the data is missing but this is not what the question is about..
auth: {
username: 'USER',
password: 'PASS'
}
})
Everything is working fine, except that Vue.js is JavaScript and therefore visible on the client side (right click -> Inspect/ View page source) and every end user can see the username and password.
What's the best practice for "storing" the password (and username)?
Even if PASS was the hashed password, the end user would still be able to use it to to an API call by himself...
From my point of view you have a fundamental design issue with your API. As it seems you want to expose some global credentials to the frontend so the SPA can in turn authenticate against the API. This approach is strange: either the endpoint is public and therefore should not need authentication or it is protected and each user should authenticate properly.
If you just want to protect the API against spam bots etc. you could send a nonce to the app and check for it in the subsequent request. This by no means is a robust protection but makes sure that each POST requires a GET and some parsing on the spammer's side.
If you want your users to be authenticated across multiple requests you should use well established methods to provide a session or a remember-me function. This could be e.g. session cookies (works but is vulnerable against CSRF attacks), JWT (with or without OAuth) or something similar.
But whatever you do: don't try to obfuscate shared credentials you pass around!
As a best practice, you shouldn't store password. You should create a JWT token on the backend when the user logged in or signed up. Then you can store the JWT token on your front-end(local storage) when you received the token from the back-end.
Easy Way to Encryption,
You can encrypt your password with any encryption algorithm on client-side then decrypt on the back-end with the same key.
Hard Way to Encryption,
As a hard way, for security reasons and security best practices, you should encrypt all your request end to end. Otherwise, anyone can access the user's information on public networks.
The below link includes all detailed information about the end to end encryption
https://medium.com/#weblab_tech/encrypted-client-server-communication-protection-of-privacy-and-integrity-with-aes-and-rsa-in-c7b180fe614e
You can store your Authorization header values in localStorage or sessionStorage.
Use interceptors to include the header values for each of your request
Here is sample:
axiosInstance.interceptors.request.use(function (config) {
const token = localStorage.getItem('token')
config.headers.Authorization = token
return config;
});
The value of Authorization header, stored in LocalStorage, will be automatically each time you make HTTP requests.
Note: Replace the variable token with username and password
I am using react for frontend, nodejs as backend and passport-google-oauth2 for authenticating users with googles oauth api.
When a user logs in, I create a new user or I find an existing user, set a cookie to know that the user is logged in.
The problem is in development I am using webpack development server and a node server. Therefore the cookies arent saved properly. I have tried using proxies in the development server but I haven't got it to work.
What is best practice here? Am I not supposed to use cookies?
Thanks in advance.
Using angularjs in the client , and c# in the server side.
I want to learn how can i create a website with users.
I know how to store the data in the db.
My real question is how the site remember the user session
After refreshing.
So the user dont need to login again.
Thanks guys.
Microsoft created a JWT (JSON Web Token) package for .NET Web API projects specifically for this purpose. And since you're using Angular.js, working with JSON is perfect.
There are plenty of tutorials for understanding how JWT works and securely saves a user's session like this one: https://scotch.io/tutorials/the-anatomy-of-a-json-web-token.
The idea is that your server sends your client/user a long encrypted string. The client saves it in their cookies and sends it to your server whenever you want to verify the user.
Most of the complicated details regarding encryption you don't need to worry about. Just follow the tutorials for setting up the exchange of the JWT tokens.
Back in the days, we use cookies to do this.
In the Restful html5 world of today, we can use several other options.
Websql, Localstorage, IndexedDB.
Probably you are using something like JWT to store an authentication token you use to make authenticated api calls.
The way to go, or as i do is store that token in localStorage and then, inject in every call to the api.
Then in the angular run section i check if the user is authenticated checking if i have the token stored, and if is not, send to the login page.
angular.module('Scope', ['ui.router', 'ngStorage'])
.run(function($localStorage, $state){
if (!$localStorage.authenticationToken) {
$state.go('login');
}
}
});
In this example, every time the app reloads, angular execute the run function, and checking if we have stored the token, if is not, send the user to the login webpage.
I have tried implementing JWT to my Angularjs application for a secured authentication. I have generated the JWT at server side(java) and the implementation returns a JWT to the client side after a successful login. I have stored the JWT in $http.defaults.headers.common.Authorization and also in the $window.sessionStorage. Now I could see the JWT in all all requests made by the $http service.
The part I am not clear is I dont know how to proceed from this point. What I guess is I should validate the JWT from now on for all $http calls at the server side somehow. Can someone clarify me how I should proceed for validating the client side JWT at the server side ?
Yes every time the client makes a request to the backend, you now have to supply the JWT in the header.
Inside the JWT you can have some parameters that identifies the user, like his username for example. Do not store password or other sensitive information inside the JWT.
If you are useing Java, you could create a Filter that will be mapped to a url that only an authorized user can have acces. In the filter you can make the necessary checks to see if the suplied token is correct, if it is you can let the request pass trough, otherwise you can return to the client an error specifying that he does not have access.
If you need more information, may be this is a good place to start.