I have been researching on RESTful authentication alot, and I still can't get a very clear idea, how can I design my web architecture. I have many questions that are unanswered.
I want my API to be served to mobile and web too and I am using Express v4.
I don't want to use Basic Authentication, as many posts have suggested as a simple way out, or I can use the Passport middleware, but I want to use token based authentication or something similar or better,and I want to make my authentication, so I could understand better, but I am not sure how can I achieve it.
I will simplify my intended authentication architecture below:
Registration of a new user
Client side
Post username and password to server
(I know if you want to make the connection secured is to use https connection, or else I will expose my credentials, or you got any other options besides https? or else I will need to use the public and private key with timestamp and hash my credentials before sending to server? How can i do this? Is there any other better option?
Server side
Hashed the password using salt cryptography, and stored the hashed password and salt, then generate a token ID and sent to the client, and the token ID is stored in sessions or using the REDIS database?
Isn't that using sessions violates REST again? But, if I don't use sessions, how can I store the token ID and compare it with the client side?
Client side
Since now I have the token ID, how can I store on client side?
Should I use cookie? If yes, will this violate the RESTful? And how can my mobile application store the cookie too?
What other options can I have besides cookie? I can't think of any.
Authorizing API
Client side
Now, I have the token ID, I will place this in the authorization header each time I would like to make a request to the server.
Server side
When a request is received, the server will check the token API, and compare it with the session token, if it is true, request allow else reject
Is this a standard way for Express application authorization?
I am sorry for the lengthy post, but I feel that I should really master the authentication and authorization because it is important. I do hope someone can correct my misconception of REST authentication and answer my questions or suggest me a better way to do it.
Send the user credentials encoded over https
To compare the token at the client side you can either keep it in map or in Redis store corresponding to user id and match it to consider user authenticated. It does not kills the significance of Rest as in Rest as well authorization tokens are sessions only which after expiry
Express does not have any specific or standard method of authorization , it only enables you to use any db in backend to perform authentication and authorization as required by your application
Your solution is the use JWT tokens for your authentication .You can read more about JWT at https://medium.com/dev-bits/a-guide-for-adding-jwt-token-based-authentication-to-your-single-page-nodejs-applications-c403f7cf04f4
With JWT tokens you can have a token base auth system with no sessions UID at cookies , but you have to implement logic to handle tokens that have sign out something like blacklist tokens.
Related
Problem:
I want to create a webapp with VueJS and a custom backend with NodeJS (ExperssJS and PostgreSQL). It should be possible to login with a username and password. After a successful login, the user can access secured endpoints of the ExpressJS server.
Now I am thinking how I can securely authenticate HTTP requests after a successful login.
What I consider doing:
Using a JWT and providing it in the authentication header of every request.
When the user provides correct login data, the server creates a JWT and sends it as response to the client. The client stores the token and adds it to every HTTP request as the authorization header. Because the transport is secured with TLS (HTTPS) the token should not be visible while transporting. To provide a seamless user experience the token has to be saved at the client side, so the user does not have to authenticate for each request.
So my question is: How can I securely save a JWT token for further HTTP request authentication?
Possible options:
LocalSotrage - BAD IDEA! (not really secure)
Cookie - more security (but also not perfect)
Last thoughts:
Isn't there an "absolute secure" or a "best practice" method to handle authentication for such a scenario?
P.S. I am pretty new to this field, so please forgive me if i wrote something stupid :D I am also aware that there are a lot of tutorials on how to setup something like this, but what i want to know is, which technique is the best and most secure one.
Thanks in advance!
PassportJS also support using local strategy. You might want to take a look about it. here
If you are new then it's better to use already build user authentication flow like Google login, Discord Login etc.
There is a well known library called Passport JS which makes third party login system integration a breeze.
In my case, I have a React app (using Next) that need to use an API provided by a node / express / mysql app.
My idea was to have an endpoint (/login) to provide a JWT Token based on user / password (that check the user in the database and create token based on the id of the user) and then use the JWT token to use the API endpoints (those token are stored in the mysql as well). But in order to do that, and because there is no form, I would have to store the credentials (user and password) in the client side app and therefore would be readable by anyone. Am I doing things right and if not, what are the other options to securely make the client side APP use the API endpoints ?
The React and the Node / Express are on the same domain and CORS is set by default by express from what I read. Also, HTTPS is activated.
generate web token
do encrypt using becrypt npm
store it in DB and cookie in the client side in encrypted form while the first-time user is login
create on middleware which directly accesses your cookie and check-in your database and make your user login for a long time if your cookie token match with database token. like below example
sample project : https://github.com/karenaprakash/books_review.git
refer to this full application
visit this project. I hope this will help you.
Basically the JWTs allow you to avoid using sessions completely & to not store them in DB, a JWT is like a passport that you give to a user, that states his (ID, maybe username for example), role & any other data (that is insensitive if someone sees), so you should never store a password in a JWT
Security of the JWT basically lies in the fact of that no other entity can imitate it (if you use a strong key for signature) & although possible to encrypt your JWT, you don't have to encrypt it as long as you don't put sensitive data in it. I think you should try to have a look on this website to see how the signature protects the authenticity of the JWT
So you should make the /login API, this will check your user credentials & then give him the JWT (that states he is user 'joe' for example with the role 'admin') & then you check & verify this JWT in your filters to authenticate & authorise the user for the actions in your webapp
To get the JWT, a user must provide his credentials to you in a HTTPS connection, which will make the connection itself encrypted, thus protecting his credentials from eavesdropping or man-in-the-middle attacks
I'm writing a single page web app using express and react.
I am now trying to choose the way to authenticate my users.
I want to let them register and log in with email and password and 3rd party provider like Facebook, Google etc...
I read some articles about passport and jwt (express-with-passport, jwt-with-passport), but none of them combined jwt and 3rd party provider.
The only way I could think of is to save the tokens in my db, and for each request to compare them (tokens provided by a 3rd party and tokens generated by myself using jwt)
Saving the token from a provider in my db and compare with each request makes sense, but using jwt I just need to verify the token without accessing the db.
How can I differ the tokens that I receive from the client? How can I tell when to access the db (for provider tokens) and when to verify using jwt?
EDIT:
The way of implementation I was thinking about is as follows:
- Username & password: Upon login, generate a token (using jwt) and send it to the client. Every request will include the token and the server will verify it.
- 3rd party provider: Let's say that the user is authenticated with Facebook. My server receive the token (using passport-js) from Facebook. Now I need to send the client its token. I could send the token I just received from facebook, but then how can I verify the token the client send to me afterward on every request?
So I could generate once again a token using jwt and work just like described above.
Is this a good implementation or am I missing something? I couldn't find
a full tutorial that describe all of those aspects.
Rather than using a token that an identity provider might give you, you might consider generating your own tokens based on a successful login callback to your application. Issue new tokens on every request for sliding expiration, and possibly consider the use of refresh tokens.
In your DB, you could store the authentication method for a given user (Facebook / Google / etc.) when they log in. When you receive a request with an invalid token, query for this auth method from the DB, then redirect them to the respective identity provider for re-authentication.
This will avoid DB lookups for most "normal" JWT validations for your app and gives you the full benefits of the stateless nature of the token.
I am building an application which needs to authenticate from another application (via api)which provides response status(success, failure) and an access-token.I need simple authentication where when user supplies correct credentials, I hit the api and save the authentication user name and access-token in session and have a persistent session.I have tried looking passport http and other strategies.But I don't think they serve this use case?Kindly let me know if I am wrong and what is the easy and effective way to achieve this.
You don't need store access-token in session.
The easiest way is use JWT (JSON Web Token) - http://jwt.io. When user sends username\password credentials to your API, you check if these credentials is correct. After that you are signing JWT and respond to the client.
When client sends to you signed access-token, you can check it with passport-jwt module - https://www.npmjs.com/package/passport-jwt.
I am creating an API using nodejs and express. I need to provide local username/password authentication. I may need to provide additional authentication in the future so I am using passportjs as it seems the most flexible/plug-able.
The API will be used by a web application as well as a mobile application. Instead of having to pass the username/password with every single api request I was thinking I could let the user login and provide the client with a token. The client can store the token and provide that on each api request.
I have looked at using JWT tokens ie, http://coderead.wordpress.com/2012/08/16/securing-node-js-restful-services-with-jwt-tokens/. However I am not really sure how to create a secure token with JWT. I have read that using the username in a token is a bad idea. Has anyone use JWT in node to create tokens. Got an example?
Any other modules for node that I can take a look at for token generation.
node-uuid is the module you are looking for. I use it to authenticate the users and any task that requires a random and unique identifier. Encoding the credentials in the token is generally a bad idea.
It was already built into nodes crypto pacakge.
http://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback