I have my site configured to login with email/password (no user name).
I have login, forgot password, and password reset pages working as expected, largely based off of this guide and a lot of poking around. I'm at a bit of a loss looking for a more comprehensive or "advanced" guide for controlling user account behavior.
Currently, a registered user can "invite" another user by simply putting in their email address. This person receives an email which brings them to the login screen, but since there is no password set yet, this person must
Click on the forgot password link
Input their email
Follow the link from the reset email and set their password.
I'm trying to work out how I would get the initial invite email to land the person on a "set password" page.
Even a link to the relevant material is greatly appreciated! I have a feeling I may just be searching for the wrong things.
I haven't done it myself, but off top of my head, as an idea (requires Iron-Router ($ meteor add iron:router)):
1) Send a link to an invited user with the query in the link that equals this user's email (q=email#address.com).
2) Use Iron Router to fetch that query (this.params.query using, perhaps, onBeforeAction method).
3) Put the query into a Session.
4) Within Template.myTemplate.helpers() create a new helper that will display the session.
5) Inside your template: <input type="text" name="user_email_from_session" value="{{helper}}">
Hopefully my approach is not too newbie, but even if so, maybe it will serve you as an anti-inspiration :)
Meteor calls "invite" emails "enrollment" emails.
1) Create a new user on the server (doesn't need a password set).
2) Call Accounts.sendEnrollmentEmail(userId) on the server.
3) User receives an email with a link to set their initial password.
Docs: http://docs.meteor.com/api/passwords.html#Accounts-sendEnrollmentEmail
Related
What I want
I have a list of people with all their personal information (name, first name, date of birth, email, etc.). I created an account for each of these people using their email/phone + a password I generated for them.
I want to send to each of these people an email/SMS with a link allowing them, once clicked :
to be directly connected on our website, without having to type a password or using a third party as Google/Facebook/etc.
and I want the link not to expire after the first use. The user must be able to click on it several times and be connected to our website each time.
What I tried
This is what I tried so far, unsuccessfully :
Passwordless Auth with email link: using both backend and frontend. Doesn't fit my needs because the signin link works only once by design.
Create a custom token with Firebase: as I understood, the token will expire 3600 seconds after creation, which is not useful for me.
Implement anonymous auth: it still need the user to type email+password at some point if you want to convert the anonymous account to a permanent account (because I don't want to use Google/Facebook/etc auth). Plus, it will need consequent changes in all my website code to work.
At this point I realized that Firebase doesn't have a solution that fits my needs. I started to fiddled around as best I could.
The idea
It works as the following:
First I create an account for the user in Firebase + a unique document in a collection in Firestore. That document contains 3 fields: magic_token, email, password.
Then, I create a link to our website with a unique token as a parameter in it. I store the token as magic_token in the document I described above. I send the link to the user.
The user clicks on the link, get redirected to my website. In the front, I detect the presence of the token in the parameters of the URL, I retrieve the document in Firestore with the corresponding token.
Using the email and password stored in this document I call: signInWithEmailAndPassword() to login the user.
PROS:
it fits my needs.
it is easy to implement
CONS:
the user password is visible in Firestore.
it's not very secure.
The question
Is there a proper way to implement a Magic Link that fit my needs? If not, how can I improve my own custom token authentication ?
I have a list of people with all their personal information (name, first name, date of birth, email, etc.). I created an account for each of these people in my database. I'm using Firebase.
Since I already have all my user's info, I don't want them to type it again when signing up to my website.
So I created a system using a custom token for authentication. I send them as a parameter of an URL to every one of my users.
When the user clicks on the link for the first time: he gets redirected to the signup page with all the fields pre-filled (name, date of birth, email, etc) except for the password. He types the password he wants and gets signed up.
When the user clicks on the link every other time: he gets redirected to the login page. A simple email + password interface with the email field already pre-filled. He types his password and gets logged in.
This is working great BUT I'm wondering: is this bad practice to do so?
Is this insecure to let anyone who gets the email create an account in the name of my user? Should I assume that someone, other than my user, may have total access to my user email account? Should I be prepared for this eventuality?
Since I already have all my user's info, I don't want them to type it again when signing up to my website.
If you already have the user's information, and you are allowed to process it, then it's a good practice to not let the user do something that it's already done.
is this bad practice to do so?
Not at all. That seems to me like a practice that is present almost everywhere. If you want to edit the profile data, you always have the existing data already pre-filled. The user has just to verify it or change it if needed.
Is this insecure to let anyone who gets the email create an account in the name of my user?
That sounds not like the best option if someone else can use that URL and create an account on behalf of the user. Most likely you should consider letting the user create the account only if it can validate the data through an SMS, or any other service that is specific to that user in particular.
Should I assume that someone, other than my user, may have total access to my user email account? Should I be prepared for this eventuality?
Yes indeed. You should always prepare for that. Never trust the users. There's not a perfect world out there.
I'm building a Membership site using wordpress and Membership Plugin .
The site is still on my localhost. I did some trial sign ups and it worked perfectly well. But I noticed that, I can use even a fake email address such as xyz#gmail.com or something to sign up and create an account. So that's the problem. I don't know how this will work when I moved the site to my server.
But do you guys think this is a security hole ?
And what can I do for this as a solution ?
Here's what I suggest:
On the registration page, add a field where users need to enter a special code to complete registration and make the code as an image (or at least as something robots cannot process easy). This will prevent robots from constantly signing up to new accounts with bogus information.
Next, perform basic email validation to make sure the format is correct.
Next, strip the email address the user entered and verify the domain part is correct and if it is, have your server automatically send an email to the new account holder asking him/her to return to a special section of the site where he/she enters a special registration code assigned to him/her to complete registration.
Also, to save database space (I'm assuming registration info will be stored in one), ask users to complete registration within a limited time period or they will have to start over. If the time is up then relevant data from the database can be removed. I suggest setting the time period to at least one day.
If you are unable to do this, then you may need to find a better plugin that has the functionality I described.
And whatever you do, play with the website on localhost and make as few modifications on the live server as possible. This means make all changes at once on localhost if you can then upload everything at once to the live server.
In my appliation,all pages are protected,so they must login to visit the pages.
And the admin of the system can add users.
Now some people told me that I have to prevent people login at the sametime using the same account.
That's to say if there is a user named "John" logined to the system,so other people cannot login with "John" again event he know the password.
Also,if one user find that someone have logined use the account he wanted,he can make the former user offline. If so I have to judge if the current user have been offed ornot in each page. This is not a work can be done easily.
I wonder if this is necessary?
Since I found so many websites nowdays do not limit this,for exmaple,you can use the same account login your gmail/stackoverflow/yahoo and ect in different machine at the same time.
So Any one can give me a suggestion?
Update:
Now,we use the asp.net's form authenciation,(we do not use the membership yet). And in the t_user table in the databse,we have a column named "isOnline" and "last_login_time".
When user login,we set the "isOnline" to 1,and store the login time.
When another user try to login again,we check the "isOnline" and the time:
if("isOnline"==1 && DateTime.now-LastLogiTIme <40min) // where the 40 min is the form authenaication timeout.
thisAccountHasLogined=true;
But suppose a user logined yet,then he clean the browser cookie,then if he refresh the page,he will be redirected to the login page,but not he can never login again before the form authentication time out because the "isOnline" in the db is 1 and the time span from his login to now does not large than the form timeout.
I am confused.
In some scenarios, I could understand not having multiple logins, but in reality, I have never had to implement it.
Unfortunately, I do not believe there is a standard mechanism for determining if a user is already logged in and this would need to be done by additional logic. In our application, we use a database for storing session information and using this, it would be a simple process to see if a session already exists within this for the user and not allow login if so.
Update
I was interested in this myself and found this;
http://msdn.microsoft.com/en-us/library/system.web.security.membershipusercollection.aspx
and this
http://msdn.microsoft.com/en-us/library/system.web.security.membershipuser.aspx
Using those, it may be possible to get this information with the .IsOnline() However, this does make the assumption you are using standard asp.net membership
the table where you store user name and password add a column status
when a user attempt to login update status to "Online" when logout update status "Logout"
During login check status, if status is online , terminate process. This may be an approch to implement this, hope it will help you
net website, i would like to implement forget password. I am using following steps
Form having input box for login Id and email Id and CAPTCHA
when user enter details and submit, at backend after validation new password is generated and replaced old password at database.
New passowrd is send to user at email.
Please help me whether i am doing right or not?
Is there any other secure mechanism for the same?
[EDIT]
Thanks, i got your reply. Really this is a secure mechanism. But here i have few doubt
What message should i shown to user when he enter loginId and email address at forgotten password page?
Whether message would be same for valid user and mallicious user?
Advantage of using CSRF token? Any help / link
When user click on link then what should i do; because as i guess user should automatically loggin into their account -then after that i have 2 choice (first) send new password automatically to user (second) new form will shown to user where user will enetr old password and new password twice?
Please help?
I can see why you'd want a CAPTCHA, but I'd take a different approach.
When a password reset is requested check that a reset has not already been requested for that account within the last X minutes. If a password has already been requested ignore the reset request.
Check the IP requesting the password reset. If that IP has requested a password reset in the last Y minutes ignore the request.
If the checks in 1 & 2 pass check the account exists. If it doesn't ignore the request.
If we've gotten this far generate a one time token, which expires in Z minutes and a password reset URL which encompasses this token. Email this to the registered email address. When the URL is loaded prompt for a new password and reset.
For those who believe that you should tell the user where the email has gone I strongly disagree. This is "information leakage", even if you do limit it to the domain name. For example say I've registered on JeffAtwoodEatsBabies.com as blowdart. If Jeff had requested a password reset for me and you showed the registration domain then he'd see idunno.org. This is my personal domain and thus Jeff would know the blowdart user is, in fact, me. This is a bad bad thing. I should not have to register using hotmail or gmail or whatever in order to protect myself from your code showing an email domain to all and sundry.
In addition you shouldn't be showing error messages at all. No matter what happens, a username is not actually registered, or too many requests have been made or the sky has fallen you should be telling the user that the password reset procedure has started. Informing a user that an account doesn't exist is more information leakage.
One final thing you could do is add a CSRF token to the reset request page, so it cannot be driven from other web sites.
Followup
So to answer your further questions.
What message you show is up to you. "Instructions for resetting your password have been emailed to the registered email for this account" is one idea, but really it's down to your audience.
Already addressed above.
Wikipedia is a good starting point. How you do it depends on your platform and is a complete other question! For ASP.NET you could look at my codeplex project, http://anticsrf.codeplex.com or look at ViewStateUserKey.
When the link is clicked I would first validate the token in the URL against the username it's being applied to then I would either allow the user to enter a new password, or generate a new one and email it. You can't prompt for the old one, as the whole point is the user has forgotten it!
There are many ways this has been implemented. As you said, generating a new password and sending it to the registered email address is one method. I wouldn't suggest you go that route though, as my password would be reset everytime somebody tried guessing my password.
Instead, the best thing I've seen to date is simply emailing the registered email with a link that will begin a password reset process. You may even let the user know which email address to check by showing a masked version of their email address used in registration:
An email was sent to ********#hotmail.com. Please check your inbox to continue.
Be sure to keep in consideration those of us who may forget which email address were registered with - typically a few security questions are a great way to make that information available.
I've done that recently. When the user enters their username or email address, we generate a unique token and email it to them as part of a link. Upon receipt of that email, they click the link, and are automatically logged in, taken to the my account screen, and prompted to reset their password.
Of course, this relies 100% on the security of the email client, but it's hard to beat from a usability perspective.
You shoud check the answer to the question : Can anyone provide references for implementing web application self password reset mechanisms properly? from D.W. on security.stackexchange.
It is the most complete answer I found on the subject. I also suggest you to read this article : Everything you ever wanted to know about building a secure password reset feature