It seems that various popular authentication gems including devise are heavily built around email. However in some developing countries, a lot of users don't use emails at all and prefer to do the verification by SMS verification codes. It seems to be possible in devise to allow users to sign in using something other than email address. However is it possible for the user to recover his/her password by cellphone as well?(i.e. just sending the new password to his/her phone by a SMS service).
Also, it is not clear to me from https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-sign-in-with-something-other-than-their-email-address whether I can ditch email field in the sign up form altogether, or just make it not mandatory, but still there?
If the above cannot be achieved, then is there any alternative gem solution available? I see gems like https://github.com/binarylogic/authlogic seem to be method-agnostic enough. But I'm not sure whether the better solution would be to just build my own authentication system instead of using any gem. I see on RailsGuide that it's preferable to use a gem to do authentication but I'm not exactly sure why.
Thanks!
If you're certain you want to use SMSes for login, I recommend you ditch devise and roll out your own authentication method.
However there are a few things to consider:
The deliverability of SMS is lower than emails. There are
countries with strict no automated SMS policies (e.g. India) and
countries where SMSes don't work at all (e.g. Myanmar)
To alleviate the above problem, implement fallback to voice (take a
look at Nexmo's text to speech API)
Keep in mind country specific restrictions
If you send out a lot of SMSes, spread the load across multiple numbers
For safe storage of passwords
use has_secure_password
I would suggest that you implement your own authentication logic if you are not comfortable with overriding devise way of using emails for authentication. For understanding how a simple authentication is done please look at this book by Micheal Hartl. Replace confirmation by email with confirmation by sms one time password or something of that sort using an API like Twilio.
Related
In my Rails app, we use Devise gem for authentication and authorization. But for viewing some of the pages clients want a second password to be entered who will act like super users. This is not an Multi-Factor authentication request, but a kind of One Time Password (OTP) for a given set of pages/resources, just that the OTP will be static.
Devise does not provide this feature. Googling hasn't helped. Any idea how could this be achieved?
This sounds like a bit of an anti-pattern. Why not have an additional field on User that denotes if the user is a super user or not?
This has the benefits that:
there is no password to remember and distribute
super users have one less step to perform
you can easily remove users from this group, if needed
you don't need to build a secondary login form/page
I'm finding a solution to detect cheaters creating many accounts at my website.
I have found permanent cross-browser cookies: http://samy.pl/evercookie/
But it written on JS, and I need something to use in rails controller. Is there any gem or plugin like evercookie?
Once I was searching for Evercookie solution for Rails, didn't find and wrote a gem 'evercookie'. You can try it.
Documentation is available on github
Email token (Devise, Sorcery)
Can you send an email to a new user?
A simple solution that many websites use is sending the user an email with a security token. A good Rails gem for this is Devise, and another is Sorcery which makes it simple to build your own custom authentication.
Third-party sign in (OmniAuth, OpenId, Facebook Connect, Twitter, etc.)
Can you authenticate the user with a third-party service?
The OmniAuth gem can connect to many third-party services and let the user authenticate using an existing account on Google, Yahoo, Facebook, Twitter, LinkedIn, and open services including LDAP and Shibboleth.
The OpenId gem works well with Google, Yahoo, and many other large providers; you can also use OpenId within OmniAuth.
In all these cases you would track the sending, so that a user can't apply again too quickly by using the same phone number, postal address, credit card, etc.
Phone Message (Twilio)
Can you send your user a text message?
The Twilio gem enables sending text messages to phone numbers. The concept is that your
app sends them a text message with a verification code.
Snail mail (postalmethods)
The postalmethods gem lets you send real, physical postcards in the postal mail. You can send a postcard with a verification code. This may take a few days, so some sites use this in conjunction with a "probationary period" for new users where they are somewhat sandboxed from causing any trouble. (for example, they can read info, but not post info).
Credit card (BrainTree)
Related ideas are to have the user send you something that requires a credit card, such as using a payment gateway like BrainTree or ActiveMerchant.
You can verify the card is open and valid without charging any money to it. Or you could require a tiny minimum payment, such as requiring the user to send you one dollar via PayPal, Google Payments, Amazon Dev Pay, etc.
Credit card numbers have internal structure (like a checksum) so you could verify that the number is the right format and checksum. A simple script is flame.org
Image Captchas (recaptcha)
To block bots, captchas such as Ruby recaptcha work very well.
Ruby has other captcha solutions and any of these are likely fine.
Karma (hypothes.is)
This isn't a gem, but it's a concept. Give new users limited privileges, such as read-only access. Let users earn new privileges by being a member for a certain amount of time, or by contributing content, or by connecting with friends and peers within your site, etc.
This is how sites like StackOverflow work, and there's a lot of good information about these approaches at http://hypothes.is
Combos
The most powerful approach is combinations of these techniques.
Perhaps give a new user some basic capabilities, such as reading information, and then let him earn new capabilities by doing one or more of the authentications above. This is how Google and Facebook add some features: you can sign up easily, then authenticate other emails, then authenticate your phone number, then authenticate your postal address.
No, there is no Rail drop-in solution and it wouldn't make much sense.
evercookie is written in JavaScript and additionally uses a SWF (Flash) object for the Local Shared Objects and PHPs for the server-side generation of cached PNGs and ETags.
Almost all of the Evercookie techniques rely on special Javascript APIs to the browser, so there's no way of porting them to a server-side technology (except for the small PHP part).
A gem might make integration and updates easier, but it would still be Javascript for the client side.
Please consider the ethical implications of Evercookie. It is a proof of concept, not a tool to be widely used, in my opinion.
If you want to roll out your own solution, a good starting point (with cookies) would be:
def create
if cookies[:xyz]
render :text => 'cheater!'
else
# save the user first (you may need to display the form again), and then set the cookie
cookies[:xyz] = { :value => "1", :expires => 1.day.from_now }
end
end
EDIT: this is not comparable to evercookie, just a simple alternative.
EDIT 2: I already said that captchas are what the author should probably use, so am I being downvoted for showing what a starting point would be if he still wants to use cookies?
I'm now on level 7 of Hartl's rails tutorial book and I'm starting to think about my application in deployment. It's an app that allows about 12 social workers to communicate collaboratively and privately. Thus, I need to password protect it.
However, it also needs to be easy to use, very easy to use. A few of these people haven't used a computer before, and having logging on and sign-up processes would put them off completely.
Thus I want to create a landing page, where they have to type a password in (the same password for everybody), then it redirects to the 'discussion pages.' My first idea was to use some obfuscated javascript such that upon typing in the password, it redirects them to the discussion pages, but this doesn't sound very secure.
Can anyone recommend me a better way to do this in rails? Ideally they would only have to type it in once, and then it would authenticate them for all the pages automatically (by setting a cookie?) and anyone trying to access a page directly would be redirected to the authentication page.
Cheers in advance
A very simple authentication option is available to you in this situation. I would suggest you watch the Ruby on Railscast episode 270. I think it just maybe what you are looking for.
If you want really simple, you can use authenticate_or_request_with_http_basic
It's not a replacement for a real authentication system, e.g. Devise or AuthLogic however.
I started to use the lockup gem for this purpose:
https://github.com/gblakeman/lockup
It is super easy to setup and almost every user accessing the site should be able to use it.
I am building an api for others to use. This is a simple enough Json request the user passes as some data and we pass some back.
What I would love is to secure our api and have some sort of user system where we can turn users on and off and we can log how many requests each user makes.
What would be the best way to do this in Rails? I don't want it to slow down the request. I can see ways of doing it using devise maybe but would be great to hear other people's opinions.
Thanks
Another way is to use 3scale (http://www.3scale.net) - it's free up to a traffic cap but handles all the key management, users, documentation etc. and there's a ruby library which you can drop into your code if you're using rails. (other libs are here: https://support.3scale.net/libraries).
I've done this before using the Token Authentication capabilities of devise (see https://github.com/plataformatec/devise ).
I found the following setup works:
Create a user account for each api user.
Configure devise for token authentication
Set the Token Authentication configuration to require the token to be submitted with each request.
This will allow you to enable and disable individual users as well as to track every request back to the api user that made the call.
If you're really interested in tracking usage you may want to consider also creating a database table where you track all api requests. This can be setup to belong_to the users table so that you easily find all requests from different users (e.g., #user.api_requests).
The count of all requests made by a user would be:
#user.api_requests.count
# or use a where clause to find how many of each type
#user.api_requests.where("api_request_type = ?", 'SomeAPICallType').count
One final note -- I recently used the Grape library for building out an API. I thought it was pretty well done and it worked great for our needs. I especially like the ability it provided to version APIs. Details are here: https://github.com/intridea/grape/wiki
I have an application built in PHP/Symfony. Part of it requires sending what is essentially an account verification email to users. Unfortunately, it seems that my email is triggering spam filters (gmail, hotmail, probably others) and not making it to the users inboxes.
What strategies can I use to avoid being filtered?
Rather than sending mail from the server where your website runs, it's better to use trusted external mail server. You can do that with Swift_SmtpTransport.
You can even use your gmail account for that purpose: http://www.symfony-project.org/more-with-symfony/1_4/en/04-Emails#chapter_04_sub_sending_emails_via_gmail
Email filters use different strategies for detecting autogenerated emails. Each email filter is different, but your best strategy would be to make sure that you actually creates an email that complies stricktly to the email standard. Include all relevant headers. Make sure that you use the correct encoding for international charachters etc. A well formed email will usually get a better score.
And of course use an email proxy with a good reputation.