Forum: Ruby on Rails check for valid email address

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
(Guest)
on 2008-10-11 23:22
(Received via mailing list)
Hi,

   I have one small question. I want to check for existence of email
address. Means if user types "removed_email_address@domain.invalid", my model 
should
throw an error to the user saying "email doesn't exist please check it
once".  How I can do this??

Thanks,
Ramu
Freddy A. (Guest)
on 2008-10-11 23:39
(Received via mailing list)
Do you have this user registered at your site with an email address?

There is no way to "test" a existing email with ex. google or other
email hosts. (The smtp protocol allows for this but its a spam trap to
have this available... )

You do have the ability to test if the domain exists and is a valid
domain.. But again this can't be 100% because not all servers allow
this inquiry and your connection to them might timeout

This would validate the domain (but could fail if you timeout.. ):

require 'resolv'
def validate
  unless errors.on(:email)
    unless valid_domain?(email)
      logger.debug "[DEBUG] - Domain name #{email} has a problem."
      errors.add(:email, 'domain name appers to be incorrect')
    end
  end
end

def valid_domain?(email)
  domain = email.match(EMAIL_PATTERN)[2]
  dns = Resolv::DNS.new
  Timeout::timeout(SERVER_TIMEOUT) do

    # Check the MX record
    mx_records = dns.getresources(domain,
Resolv::DNS::Resource::IN::MX)

    mx_records.sort_by {|mx| mx.preference}.each do |mx|
      a_records = dns.getresources(mx.exchange.to_s,
Resolv::DNS::Resource::IN::A)
      return true if a_records.any?
    end

    #Try a straight A record
   a_records = dns.getresources(domain, Resolv::DNS::Resource::IN::A)
   a_records.any?
   end
rescue Timeout::Error, Errno::ECONNREFUSED
  false
end

Using a pattern is faster and just plain easier...

EMAIL_PATTERN = /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
validates_format_of :email, :with => EMAIL_PATTERN
(Guest)
on 2008-10-12 00:23
(Received via mailing list)
Thank you very much! Any more ideas on how to validate the email
address existence.
Ramon T. (Guest)
on 2008-10-12 00:36
(Received via mailing list)
This doesn't exactly answer your question, but I think it may answer
your concerns. Send an activation link of some sort to their email
that they need to use to join your website.

That way, if it exists, then they get the email.

Ramon T.
Youssef Chaker (Guest)
on 2008-10-12 07:44
(Received via mailing list)
What i have done is the followring (it is sort of a summary or a
combination of what @freddy and @ramon said):
first i check that the email is in correct format using this chunk of
code:

# validate that password and confirm_password match, and that email is
proper format
  def validate_on_create
    @email_format = Regexp.new(/^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})
$/)
    errors.add(:email, "must be a valid format") unless
@email_format.match(email)
    errors.add(:confirm_password, "does not match") unless password ==
confirm_password
  end

which is in the user.rb file
then in my controller i send an email to the user when they register
with a link back to my controller with a hash at the end of it that is
constructed through many ways (google tutorials on this, there are
plenty) and my controller validates that the hash is correct and sets
a boolean attribute of the user (call it email_confirmed if you will)
to true. So the user can not log in to the site unless they have
confirmed their email.

The other approach I have seen many site implement is to send the user
their password to their email, which means they have to provide a
valid email address to be able to log in. I am personally not very
comfortable with sending a password through an email so I prefer to
stay away from that method.

But again, these are not perfect methods, they're just a way to do
what you want to get done. Maybe if OpenID picks up we won't have that
problem anymore.
This topic is locked and can not be replied to.