So basically I have a registration endpoint in my express app. I am trying to make it so that users have to verify their email prior to their account being activated(the account is deactivated by default). I have everything set up, the only thing that is confusing me is how to create a hash that I can send as part of a link that a user clicks to verify their account. I have thought of using JWT and just creating a token and sending that along, however this seems a bit overkill. So my question is, is using JWT for this purpose a solid solution or is there a better alternative? If so, what is that alternative?
Thank you!
This question can lead to opinionated answers and I will try to give you one.
If all you want to do is verify email, then JWT seems like an overkill to me. Just create a hash using nanoid, shortid package from npm or using standard nodejs crypto.
Save the hash to DB record of the user, send out the link as in
https://my.server.com/whatever-path-you choose/${your-generated-hash}
This should be handled by the server where the endpoint:
looks up and verifies the user by the hash
enables the account
burns the hash (i.e. delete the hash from DB)
redirects to the page of your liking, most probably login page.
My 2 cents.
do a token that includes user id and a secret value to make it more safe but don't push your code online to hide this secret
also then put it as a cookie
another way without jwt is using res.locals
Related
I'm using react-native and firebase for my login/signup system.
I want to add the feature that when you signup with a mail and password you receive first a mail that you need to confirm before you can use that account for logging in.
I searched for documentation about it but i couldnt find anything that really fits to the feature.
This have been covered quite a few times before, so I recommend searching for previous answers. For example: https://stackoverflow.com/search?q=%5Bfirebase-authentication%5D+verified+before+sign+in
But nowadays I'd probably use an email link to sign in to Firebase, since that automatically ensures the email account exists.
I didn't work a lot with firebase but iirc there was a way to return a token when signing up and sending it when signing in later.
There is also a way that doesn't involve tokens which is to add a boolean to your DB and send an email with a certain randomly generated id. When the user clicks on the link in the email, you could then send that key to the backend and set the boolean to true.
This approach works as I personally tried it before but it needs effort to make.
This is a pretty open question but I just can't get a straight answer no matter where I look. The question is in the title but...
Should I return the user's encrypted password or token on user login
Extra Info
I'm running a MEAN stack application with Angular5. I'm using sessions for the user and storing it in MongoDB. So from what I understand, the session cookie is what used to authenticate the user for extended sessions and not the password (I haven't gotten to Facebook or Twitter strategies but from what I understand the cookie verifies the user instead of the token that Facebook/Twitter gives me correct?).
I do want to pass user data to my Angular application and store in the browser local storage for quick, non-server-side verification that the user is logged in. This is only for aesthetic reasons such as displaying username and profile picture. Restricted POSTs and GETs still require server-side verification using a passport. So my question is since the session is saved in the cookie, is there any reason to send the password or token to the user/browser? Even though the password is encrypted (using bcrypt), it still seems like an unnecessary security hole to send it at all. Is there a reason that I might encounter in the future where I would want the password stored in the browser?
The quick answer is no, you do not and SHOULD NOT pass the sensitive data back to the front end.
What I normally do is when I return a "User" object back as a response to the front end, I run it through a helper function that filters out sensitive data such as the encrypted password and the salt, etc...
I know of two ways of storing and authenticating the user login info:
Storing the user id in a server side session and then when someone calls to the server check if they have a user session. (Using node client sessions)
When the user logins, store a authentication token in the user's table and store the token locally on the users client as well. Then when the user calls to the server they send the authentication token as a header and check if the token is in the user table.
While both of these ways are viable and applicable, I have problems/questions with both of them:
I've been told storing the info in session goes against the rest api idea of auto scalability. Is this true and is there a way around it?
When storing the authentication key, won't you only be able to store one key/instance per user. What would you do if you wanted to have the same account logged in on two computers or clients (I know I can just create an authentication table, but what if a client loses a token and the authentication token stays forever in the authentication table).
If there are better ways of doing this please bring it up, but I am very confused which direction to move towards. I am gravitating toward the second way, but I still like the first way.
Edit: I have narrowed it down to JWT and my second idea. I don't know which would be better with node.
How about JSON Web Tokens? They're a variant of the second method you mention and are a recognised industry standard, so you can easily find an implementation for your stack.
You can store the tokens in a key-value store like Redis instead of a relational database, which will be much faster. Redis also supports timing out a key after a while, so expired tokens will disappear automatically. You can also set it up so that each token is invalidated once used, and any request to the API returns a new token for use in the next request, allowing users to continually refresh their token.
Assuming you are using express, you can use express-session for managing your sessions.
Then, you need to add a suitable session store instead of the default MemoryStore, which is for debug use only, and will not scale to more than one process instance (for the reasons you mentioned in your question).
Fro example, if you are using a PostgreSQL database, you could consider using connect-pg-simple. This would store your sessions in your DB, so that your session management does not prevent you from scaling your node.js server. In addition, you can store multiple sessions per user, that will expire (and get automatically erased) based on the maxAge that you configure, thus solving the second problem you mentioned.
This is absolutely a newbie question & I am Node.js beginner.
I am not sure, this is right place to ask this question. But I may need idea from this large community. So let me explain what I am trying to do.
Server Configurations:
Node.js - 4.0.0
Hapi.js - 10.0.0
Redis
Scenario:
I am writing a proxy server in nodejs using hapijs. My Backend is ATG based e-commerce website and my api's are going to be consumed by web browser, mobile app etc..
We planned not to send the cookies sent by ATG to both browser and mobile.
So to maintain sessions and cookies from ATG,this is how we done POC.
First We planned without considering storing the anonymous user cookies returned from ATG. So we have done two POC's.
(Many of us know, what anonymous cookie is,any way let me explain that, if I put that one word -- Guest Checkout. There are many ways to accomplish this. But my Commerce Backend is implemented like this, When we go to website, you add items to cart and checkout that items without logging in right ? This what happens on background whenever we add the items they are only stored in your browser cookie,it not stored in persistent database, in any case user wants to login/signup to the account that cookie is retrieved from the browser and stored in database (basically that anonymous cart is transferred to logged in user.))
POC-1 (Not Considering Guest Checkout):
To access my api, user must be logged-in, after the successful login, We generate a rand-token and store it in Redis db associated with the cookies sent from the ATG for logged-in user and set ttl for 1 hour and return that token to the client
Now whenever they invoke any of api methods, they should send the token in the authorization header, I will check for token validity and expand the ttl once again for 1 hour and retrieve the cookies associated with that token, set that cookies in ATG request options and make a request.
3.On logout, I will clear the cookie and delete the token.
I have successfully implemented JWT fot this scenario, by generating a JWT token with user logged-in information in jwt payload. Used hapi-jwt-auth2.
POC-2 (With Maintaining Guest Cookies),
My API Will have endpoint /auth/generatesession, which in turn will return a 64 byte random token (we are using rand-token npm module for that) which will expire in 24 hours.
All the methods needs that access token passed back to me in authorization header and I will extend that token ttl to 24 hours.
Now they can invoke any api methods, like addtocart or something, even after adding items to cart , suddenly they want to login or something I can use their guest session cookie and transfer that cart to persistent database after successful login.
Questions:
Should I use JWT for the second scenario? If so,
How can I implement JWT for the Second Scenario? (Coz, don't know about who is the user?)
Does anyone think this is good idea for writing proxy server like this?
How can streamline session expiry of this token with ATG session Expiry?
Does anyone of using Node.js like this? How does it scale ?
If anyone care to give me an idea how to write this proxy server, it will be much helpful for me.
I Apologize, if this is too long question, just my way of explaining things.
Thanks in advance.
Sure, why not?
You don't necessarily need a user. A JWT stores arbitrary data, the username can be blank or anonymous. If a user logs it, and provides a token associated with a guest cart, then it can be assumed that that user is allowed to claim the contents of that cart, and the anonymous cart can be destroyed.
Sure, this is quite common (disclaimer: I've worked on something very much the same as you).
TTL is reasonable, but I have no idea what ATG is or how it handles it.
Yes. It scales very well as long as you ensure your servers are stateless, and that you manage all your state through something like Redis.
Too broad of a question, I would just use Express + Redis/Mongo/Postgres.
I'm looking for a short tutorial about creating a login page for a website using cookies.
Each user has a username and a password.
Should I save both the username and the password in the cookies ? or just the username may be enough ?
Can a malicious user steal somehow these cookies and pass the authorization ?
It's not a good idea to store the password in the cookie. If you store just a username, your system is basically completely unsecure. Remember that the client has complete control over the contents of cookies it sends to the server. It can send any username it wants. You should create an authorization token for the specific session (probably with an expiration time associated with it) and store that in the cookie. To prevent tampering with the cookie, you should sign (and encrypt) it on the server and validate the signature.
That said, doing that correctly is not an easy task. Don't reinvent the wheel. Use the authentication mechanisms provided by your platform.
There are many ways to do authentication in PHP. Just google one
http://www.developertutorials.com/scripts/script-details/307067.php
You will want to store you user's passwords in a database, and keep obfuscate them in some way. PHP has a built-in function called md5().
Here's a guide on php.net to help you through.
http://php.net/manual/en/features.http-auth.php
I'f you're having trouble grasping these concepts, then I'd recommend working through a php framework. My framework of choice is cakePHP, which makes stuff like authentication a breeze (another top framework is Code Igniter).