Correct Passportjs strategy to use (hash vs jwt) - node.js

I have a Laravel app which I'm trying to convert to NodeJS. In the original app we have an API for which access is protected by random generated tokens - assigned to each user and stored in our DB. We automatically generate this secret token when a user first registers then they use it for as long as they would like to use our services. (We verify subscription details for users using these tokens).
I'm trying to replicate the same on NodeJS but I'm a bit lost about the right authentication strategy to use, as passportJS has JSON Web Tokens (JWT) and 'hash'. They both seem correct but I can't figure out the difference and which would be most appropriate in this case.
If hash is the correct strategy would I have to use JWT to generate the token and assign it to each user? Probably I haven't understood properly the concept of hashes and token for authentications. What are the differences between hashes and token for authentication purposes?

I did some more research and found out that the JWT are not exactly what we were using or what we need for our app. We simply create SHA hashes for each user based on personal details and a secret key. This hash is now created and used in the new application correctly. It was simpler than I thought. And for those wanting to learn a bit more about JWT, this Medium article could help a lot:
https://medium.com/vandium-software/5-easy-steps-to-understanding-json-web-tokens-jwt-1164c0adfcec

Related

Is it a good practice to send all the User details stored in DB via JWT token?

I am developing a Demo WebApp using the MERN stack and using JWT for Authentication.
In the Backend, when a user requests to log in, I am preparing a JWT token by adding the MongoDB ObjectID for that user in the token's payload with necessary timestamps.
On User login, I want to store the User details for that session on Frontend.
I know that I can share all those details via API response & store it using React Context/ Redux. But is it a good practice to create a JWT token from the backend with all the session-specific User details stored on DB (Apart from secure information) into Payload during login & sending the encrypted token in the response? So that, I can decrypt & destructure the user details from the JWT token and store them for that session.
Eager to know the Pros and Cons of the above process keeping best coding practices into consideration.
It seems like you need something like an ID token from OpenID Connect (https://openid.net/). This is a JWT which contains user data used on the frontend to identify user, maybe print their username somewhere, etc. It is a common practice to use it, but you should remember that if you put too much information into that token it will get quite large (which can have an impact on slower connections, or slower computers which will need to decode it, verify signatures, etc.)
Another viable option is to have an endpoint which returns all that information when needed (see the userinfo endpoint in OIDC).
You also have to remember that all that information will be readable to anyone who has access to that JWT, so no personal information should be kept there.
Just a note - I can decrypt & destructure the user details from the JWT token - you probably mean decode here. Decoding is the act of changing the JWT from a base64 encoded string into a JSON object. You can have truly encrypted JWTs (JWE), which guards them from being read by eavesdroppers, but you wouldn't use them in a frontend app. They are also much more complicated to set up and use more CPU.

How to generate, store and use Access Tokens in Node.js/Express?

I'm new to backend development using Nodejs/Express and I'm creating an API in which registered users will be able to make requests to it by using an unique Access Token.
I'm already using JWT (JSON Web Tokens) for user authentication and after reading a lot of tutorials about JWT, I didn't find any explaining if it's possible to use JWT as Access Tokens (instead of as Authentication Tokens) or if there is another solution to generate this kind of token.
So, basically I have some questions about how to generate and use an Access Token:
Can I use JWT as Access Tokens? Is it safe? Is there another solution more commonly used?
How should I store the Access Token? Can I just save in the user model in the database so when I receive a request I just compare if they are equal?
When making a request, should I use HTTP Authorization header to pass my token or it's better to pass it in the URL (similar to Google Maps API: https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap)?
So it's a quite broad question as it really depends on your app and the security you want to have.
If you are already using JWT tokens for login users and making sure they are authenticated that's great.
Now there are many ways you can make sure the user is authenticated in a secure way.
You can set an expired key inside the JWT, so it will be limited for 1 hour, 2 hours, a week whatever.
If you want the users to be able to log in only once you will need to dig a bit deeper into how you manage your tokens.
As for where should the user pass the JWT token in the header or in the GET params. So security wise it's similar both are accessible. But when you put the jwt in the url, there are limits to url length (I think 1024 chars)
For your specific questions on access tokens, not sure exactly what you intend to do with them.
But if it is just for providing other services to do actions on your api, so its better to store those access_tokens locally so in case you want to invalidate a key you could easily do that.

Storing secret info in JWT, using Node.js - Express backend

I am developing an Angular web app that communicates to its back-end via RESTful API. Currently I am using JWTs to store the state (current user ID, etc). I use jsonwebtoken and passport-jwt packages to implement the JWT with my Node.js-Express application.
Sometimes I might need to store in the state some information (for example, a secret encryption key) that is relevant to the session, but that should not be known by the user.
Since the JWT payload is signed but not encrypted, its contents are plainly visible to anyone who cares to decode it, it is not appropriate to store secret content directly in the payload. While I could implement some kind of self-made encryption either of the whole JWT string or just the secret variable value in the payload, I am looking for the "right" or "traditional" way to handle this.
The best way would be to store it only on the back end in some kind of persistent storage preferable hashed.
If that isn't possible then you can store in the JWT but you would need to encrypt the data before putting it in there.
Bcrypt is probably the easiest solution that is still secure is https://www.npmjs.com/package/bcryptjs. Be aware that the more secure you want it the slower the encryption will be.

Generate token after login nodejs API

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

How would an efficient OAuth2.0 server / provider work?

I may need to implement an OAuth2.0 server for an API I'm creating. This API would allow 3rd parties to perform actions on the user's behalf.
OAuth2.0 has 3 mains calls. First, there is a call to prompt the user for consent. This returns a code. The second is where the code is exchanged for a access token. Finally, the access token is used to call the API on the user's behalf.
For implementation, I was thinking the first call generates a random string which acts as a code. The code is then stored in a database with a pointer to the current User and a random HMAC Key, then the random data is returned to the 3rd party as the code.
When the 3rd party requests an access token, another piece of random data is generated and concatenated with the code. This string is signed using the HMAC key from Step 1, then this signed string and signature is returned with the signature to form the access token.
When the API call occurs, the hmac key corresponding to the provided access_token is retrieved from the database. The signature of the access_token is verified using the hmac key.
The user can revoke 3rd party access by simply removing an HMAC key from their list of authorized HMAC keys. Furthermore, but just signing random data, I can avoid storing every single access_token every created, and instead maintain a short list of hmac keys.
Anyway, this is my first attempt as thinking through this. Surprisingly, there is little information about implementing the server side of OAuth2.0 efficiently. I would prefer to keep as little information as possible in the database. The advantage of signing random data then later revoking the HMAC key is that I don't have to store every single access token generated by every single authorization call.
Thoughts needed! There has got to be a better way!
EDIT:
I'm NOT looking for an implementation. Thank you though! Also, I assume this whole system will run over HTTPs. Also, I'm talking about the pure OAuth2.0 flow, I'm not talking about OAuth1.0 with signatures and client keys. I'm asking how to design the cryptography behind an OAuth2.0 server that would work in a similar fashion to (for example) Google's OAuth2.0 flow works.
I don't have an exact answer to this, but let's try to put the pieces together -
i) I am not too sure if you need to save the authorization code in your database for long. This is what Facebook says -
New security restrictions for OAuth authorization codes
We will only allow authorization codes to be exchanged for access tokens once and will require that they be exchanged for an access
token within 10 minutes of their creation. This is in line with the
OAuth 2.0 Spec which from the start has stated that "authorization
codes MUST be short lived and single use". For more information, check
out our Authentication documentation.
See this link, https://developers.facebook.com/roadmap/completed-changes/ (December 5, changes).
ii) What about doing what you are doing till step 1, keep the authorization code and HMAC key in the DB. Let's have the authorization code for 10 mins (or whatever you feel is necessary) and then remove the authorization code.
iii) Let's say you have a single sign-in service that authenticates a client's credentials. When the client app hits the token exchange endpoint (auth code for access token) you'd need to fetch the HMAC key and return the access token. Why not add (some random data + timestamp + customerID/customer name(or something that can be used to uniquely identify the user)) and sign it with the key and return all this data as the access token.
You can think about using a new HMAC key perhaps and replacing the old one.
iv) When the client hits any API endpoint with the token, let the srvice internally call a CustomerIDExtractorService that fetches the HMAC key from the DB and decrypts the access token and returns the customerID to the relevant API. The independent process can then use to the customer ID to fetch data. So basically, I ask you to separate the login/token generation/token info extraction process to a separate unit.
Let's try to map this to how Google could be doing something like this
i) You use an app and sign in to Google Oauth. (Let a black box X from google handle the login).
ii) Your app hits the token exchange endpoint -> The service internally checks if the code is valid. If it is, the service combines some data + customerID and signs it and returns it to the app as an access token.
iii) The app now hits (say) the google+ endpoint. Internally, the service transfers the token to black box X, which decrypts the token and returns customer ID to G+ service. g+ then maps the C_ID to relevant customer data.
Another suggestion
Depending on the scope that the app requested, you can add more info to the access token. Maybe create a JSON object and add/remove fields according to the scope selected by the app. Sign the JSON string as the access token.
Seems your description started off OK, but then I must confess I could only partly follow your approach. AFAIK OAuth2 relies heavily on HTTPS rather than signed requests, although I guess you're free to use such.
I'm not sure about the concept you present to revoke access. Typically this would rely just on the access token (it should expire at some point in time, you could revoke it, and it could be renewed). If for API requests you are pulling keys for a userid then possibly your code is too closely tied to "user" concepts and not OAuth clients (with role, scope, resources)
In any case it's not a simple standard and I guess the discussion could go on quite long and even then I am not sure all could be covered. I trust you've reviewed the RFC at:
https://www.rfc-editor.org/rfc/rfc6749
I see also from your profile you're likely a Java developer. In such case it may be a good idea to review Spring-security-oauth2 at:
https://github.com/SpringSource/spring-security-oauth
If your solution won't use Java a lot of the issues you allude to in your question were approached and solved by such project, so it should give you lots of ideas. If you will use Java then it may help you a lot.
Hope it helps!
Actually most of implementations are using bearer token over https not mac in OAuth 2.0, check this presentation pages 54-56 about why prefer bearer ,on other hand spring implementation is not supporting MAC token for OAuth 2.0 and there is an open issue about it but it is still open
for time-being if you are looking for spring implementation demo you can check this source code but it is using data base to store tokens, and there is connection have to be done between the resource server and Authorization server, in this demo using data base.
one of open source implementation of Spring OAuth 2.0 is UAA of cloudfoundry I attend one session about it also they were telling that there is communication have to be done between both servers. link

Resources