I am creating a REST webservice using jersey. I want to authenticate the user based on tokens. Once the user logs in by providing his username and password, I generate an authentication token using bcrypt and send it to the user.
My question is, if we send the bcrypt encrypted token to the user and store the same in the server, if some hacker get holds of the database, he can use the tokens as such and login as any user. Then what is the purpose of encryption.
I searched the forums but was not able to find a answer. Thanks in advance.
The token should contain a universal datetime that way the token can 'expire' after nn amount of time.
Check out this page: http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/
Related
While I understand how jwt works for authentication, I'm trying to build registration.
Registration has a step that requires verification.
User enters the phone number
Code is sent via sms to user
User enters the code and device is verified
Since it's an API for mobile app there is no session/cookie built in.
I'm wondering if I can not implement cookie like system for mobile. And just make it work with JWT. But I don't have much experience with this.
This is my current flow:
User makes a POST request with Phone #
I respond with JWT (Time:Number)
I also send code via SMS
User sends the code via POST and JWT
Problem:
I don't know if code belongs to user or not, as I didn't save the code in DB.
I can't put into payload as it's just encoded not encrypted. (why is it not encrypted, what's the point of sending plain payload, what's even the point of JWT & didn't signed cookies already do that? they had session string encrypted so you couldn't change session string without invalidating the cookie)
JWT is overcome authentication/authorization mostly in APIs. JWT Access Token/Refresh Token is nothing but a JSON data in an encrypted form. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA. Key pair using RSA or ECDSA is more preferable as a security point of view. You can check authentication/authorization by decryption JWTs.
JWT token itself contains expiry date, so you can just configure expiration time to it. Access tokens are to check that user is authorized or not. Refresh tokens is necessary to get a new access token, generally used when the old access tokens are expired. Refresh token and Access token both expire but refresh token is long-lived compare to access tokens.
Generally developers use access token only but it is preferable to use access and refresh token both.
I’m a little confused as to how JWT authentication works. Once a user is able to log in, my express server is responding with a token, which I store on the client side in local storage. With every request, I send that token. My question is, how do I limit a user to see his/her specific data (e.g., user profile)? Is the token alone able to determine which user is requesting the user data on the server side or would i have to send the username along with the token? Is this secure?
The JWT token will contains 3 parts, one of them called a payload and you will use it to store the user's id when he logs in. When the user sends a request with his token you will decode it and grab the id from the payload and then with a query to your database you can get the user's profile.
how do I limit a user to see his/her specific data (e.g., user
profile)?
If you get the id from the token's payload then you can compare it with the id of the profile that the user wants to see, if they are the same then it means that he wants to see his profile.
Is the token alone able to determine which user is requesting the user
data on the server side or would I have to send the username along
with the token?
No need for username, the token alone is sufficient because it identifies the user.
Is this secure?
Read this: http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions/ there are other opinions of course, try implementing best practices and I think you'll be fine.
I've been trying to understand the real differences between session and token authentication.
What I have gathered so far:
In token authentication, nothing is stored in the server side. What this means is, that the actual token includes the password and username, as well as other possible information. And the server just decrypts the token, and then checks whether the username and password are correct. Am I right about this?? If the token includes the password and username, then how can the token still be different everytime?
In session-based authentication, the session token is just a random (unique in time) id, that is mapped to the user in the server side. So that when the server receives the session_id (in cookie for example), it will check whether it maps to any user, and if it does, then the user is authenticated. So the session_id does not contain any user related information, that could be decrypted?
In session authentication, the server will send back the user related information (not password) without encryption (unless https is used).
In token authentication, the server will not send back direct user information, but just the token, which contains the user information, once decrypted?
I have a feeling that I haven't really understood how token and session authentication works. Something is definitely wrong in the statements above.
But, let's play along that the statements would be correct. Then wouldn't session-based authentication be more secure? Because in session based authentication, you do not reveal user password (in browser for example). Since it's just a random id, one cannot get information from it. But this is not the case with Token authentication. Since token authentication contains the password, if someone manages to decrypt it, he will get your password. So isn't the session authentication actually more safe than the token authentication, as it doesn't reveal password nor username information?
Your question has not an absolute answer YES/NO. For example session cookies are vulnerable to CSRF and tokens can be stolen with XSS injection. Both mechanism are also vulnerable to ManInTheMiddle if you do not use HTTPS. Therefore additional security measures are needed usually for each solutions. Depends on your use case.
I guess you are talking about a token mechanism like JWT which is self-contained and protected to alterations because you said
In token authentication, nothing is stored in the server side.
But you are confusing some concepts. I will try to answer your additional questions using JWT tokens as reference. If not, most concepts also can be applied to opaque tokens
In token authentication, nothing is stored in the server side. What this means is, that the actual token includes the password and username, as well as other possible information. And the server just decrypts the token, and then checks whether the username and password are correct. Am I right about this??
The token is issued by server (not client) requiring users to present their credentials and digitally signed with server private key. The token includes an identifier of the principal in the sub claim and other fields of interest like expiration time or issuer. Never the password
When the client send to token to authenticate, the server verifies the signature to determine the authenticity an has not been altered
If the token includes the password and username, then how can the token still be different everytime?
The token does not include the password. The token will be different due to some variant claims like expiration time exp or issued at iat. Also the computed signature will be different
So the session_id does not contain any user related information, that could be decrypted?
Yes, it is a ramdom sequence. Relationship with user server is stored on server
In token authentication, the server will not send back direct user information, but just the token, which contains the user information, once decrypted?
The JWT token includes some user information, but it is not encrypted, it is signed. If you need to hide the payload, JWT also allows to use JWE encryption
But, let's play along that the statements would be correct. Then wouldn't session-based authentication be more secure? Because in session based authentication, you do not reveal user password (in browser for example). Since it's just a random id, one cannot get information from it. But this is not the case with Token authentication. Since token authentication contains the password, if someone manages to decrypt it, he will get your password. So isn't the session authentication actually more safe than the token authentication, as it doesn't reveal password nor username information?
The base approach is wrong. Password is never included in the token. If you do not want to reveal user data you can use opaque tokens or JWE encryption with JWT. The proper solution depends on your use case. See my first paragraph
Sensitive information such as password or items like Social Security Numbers shouldn't be stored in a token.
A typical example of token signing is this
function createToken(user) {
return jwt.sign(_.omit(user, 'password'), config.secret, { expiresIn: 60*60*5 });
}
Here, we are creating a signed token with the user's details but we are leaving out the password.
I gave a very detailed information about this in this thread How is JSON Web Token more secure than cookie/session?
Check it out. I hope this information helps!
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 have a Node.js application that offers several different routes in front of MongoDB. I need to make sure that only authenticated requests can access these routes.
Ideally, I want to set it up so that a username and password comes in to the API, and in a response we give them back a token. I don't mind managing the tokens inside MongoDB myself, but I need to make sure that the token we give back can make authenticated requests. I don't want to force the user to send their credentials each time, just the token.
I've read for a few days about passport, and there's currently 307 strategies. Which strategy am I describing here?
Which strategy am I describing here?
You are describing a Local Strategy.
As per their description:
This module lets you authenticate using a username and password in your Node.js applications.
I don't want to force the user to send their credentials each time, just the token.
Passport auth strategies just provide various ways to authenticate (or in simple terms login) the user, not how to persist that login. Login persistence is usually done with user sessions.
One way you can solve this is to combine the local strategy with the express session middleware. Combination of the two allows for a fairly simple auth system that requires the user to login once and then persists the session.
In a typical web application, the credentials used to authenticate a user will only be transmitted during the login request. If authentication succeeds, a session will be established and maintained via a cookie set in the user's browser.
Each subsequent request will not contain credentials, but rather the unique cookie that identifies the session. In order to support login sessions, Passport will serialize and deserialize user instances to and from the session.
PassportJS docs give an example how to achieve this.
For this you should prefer generating JWT tokens for a the login and then using the token to always authenticate user actions.
Following steps are need to implement this style of token login system
generate token on login
verify when token supplied and use the decoded data to identify user
use should proper middleware in order to protect your api.
Here is a link you could follow:
https://scotch.io/tutorials/authenticate-a-node-js-api-with-json-web-tokens