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
Related
I have a REST API (.net) which for the initial login requires the password to be encrypted (RSA with OAEP). The reason was to obscure the users passwords from local logs.
Performing this encryption with javascript is complicated and I would need to let the client know the public key. The end user would be able to reverse engineer the encryption method then could use it to brute-force (or worse) access. So why bother, right (it is SSL Secure).
Thing is, I still need that password to be encrypted. Should I have some sort of encryption service at the server side that gives me the password to throw at the token endpoint? Why not have the service just log in for me then return the token. How should I proceed?
Thanks ^_^
This seems like a general authentication question. You can solve it like you would solve user authentication. Think of it this way:
When a user signs-in into your app, they provide their data on the client, and then it is validated on the server. In order for them to stay logged in, they get some sort of token, either via a Cookie session, JWT or whatever. Which is then saved on the client and sent on each request to the server in order to verify they are authenticated.
The above is how websites can show "registered users only" content. By validating a previously given token on each new request.
Now, applying this method to your REST Api. A user needs to request a token (which should not be your master password, but a uniquely generated one, in a per-user basis), and then save it locally for X amount of time. Every time the user makes a request to the API they send that token, which is validated.
This is also how normal APIs do it. You will need a token or some sort either way. If it's really sensitive information you're showing, the token should update every now and then (from minutes to days depending on how sensitive). You keep a record of valid tokens in your server. That way, if any token is "stolen", then it will only be valid for a small amount of time.
I am working on an authentication system, implemented the front end using vuejs and back end with nodejs. User is able to register and login successfully. I am verifying user is logged in using jwt token. My problem is anyone can login by manipulating the localStorage jwt token value. Is there anyway to prevent it.
You should be using an asymmetric signature on your JWT token, and the private key should be available only to the server that creates the JWT. If this is the case, then it's highly unlikely that a user would be able to forge JWT claims.
Here's a step by step of how your server should prevent someone from changing their JWT info:
Your NodeJS server creates a new JWT using an encryption key (we'll call it secret-key) to create the signature, and it sends the token to the client.
The user decides they want admin access, so they change their permissions in their local JWT and send it to the server.
The NodeJS server re-signs the header and payload of the user's JWT using secret-key and compares that generated signature with the signature in the user's JWT. If they match, then nothing has changed about the user's JWT. If they don't match, then either the user changed something in the header or payload, or they tried re-signing the token with their own encryption key. Either way, your server can tell that the JWT isn't valid, and you can deny them access.
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 ?
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.
I'm trying to find a way to interact securely with an OAuth (draft v2-23) API completely in the browser. There are obvious security concerns with authenticating in the browser because the auth token and other keys are exposed somewhere in the browser.
Is there a secure way to hide those keys, or am I limited to creating a server side solution that keeps track of those keys?
I came across this very concern when working with the mobile version of my application (since a normal login auth wouldn't work.)
The solution I came up with is to work with 2 keys. When the user logs in, they are initially given their token. The client already has the token saved as a variable in the app (you can make the token whatever string you want, I usually generate a base64 key of 32 length.)
So this is the basic play by play of what happens when they call the server from a GET/PUT/etc..
Send request with USER TOKEN and SERVER TOKEN as parameters.
SERVER TOKEN is checked against the server token (which is salted and hashed). (If SERVER TOKEN is good, proceed to step 3, else deny request here.
USER TOKEN is checked against the user token assigned to said user (which is salted and hashed) and makes sure it exists. If good, proceed to step 4, else deny request here.
Execute request (GET/PUT/DEL/POST etc.)
Long story short, i keep a salted and hashed version of the user tokens (which are unique to the user) and the server tokens (which is the same for every user) on the server and the de-salting and de-hashing is done on the back end.
I hope this kinda makes sense. It might not be the standard or completely right but it's what i understood token auth to be and this works for me.
If others see something wrong with my reasoning please chime in and tell me so.