Подтвердить право собственности на сайт в рельсах - PullRequest
3 голосов
/ 03 декабря 2009

Для более недавнего обсуждения подобной темы, проверьте этот вопрос вне.

Какой лучший способ проверить, есть ли у конкретного пользователя право собственности на веб-сайт?

Допустим, у вас была эта модель:

class User < ActiveRecord::Base
   has_many :websites
end

Чтобы удостовериться, что Пользователь действительно владеет тем веб-сайтом, я подумал о проверке электронной почты. Пример: пользователь указывает example.com в качестве своего веб-сайта, и на адрес username@example.com отправляется электронное письмо. Если пользователь отправляет ответное сообщение с сайта example.com, веб-сайт проверяется.

Проблема в том, что существует веб-сайт, на котором большая группа людей может отправить электронное письмо с веб-сайта с таким доменным именем, например gmail.com. Я бы не хотел, чтобы пользователь регистрировал gmail в качестве своего личного веб-сайта.

Таким образом, кажется, что лучший способ сделать это - заставить пользователя встроить некоторый код в HTML, и приложения rails обеспечат его присутствие.

Как бы вы поступили так?

Ответы [ 5 ]

8 голосов
/ 04 декабря 2009

Вот как вы можете проверить домен, используя подход поддомена Google в стиле RESTful. Вы разрешите пользователю создавать запись сайта, которая будет оставаться непроверенной до тех пор, пока пользователь не нажмет ссылку / кнопку, чтобы подтвердить домен позднее (чтобы разрешить распространение DNS).

Этот код не проверен, но поможет вам начать работу.

Модель:

class Site < ActiveRecord::Base
  # schema
  # create_table "sites", :force => true do |t|
  #  t.string   "domain"
  #  t.string   "cname"
  #  t.integer  "user_id"
  #  t.boolean  "verified"
  #  t.datetime "created_at"
  #  t.datetime "updated_at"
  # end

  require "resolv"

  YOUR_DOMAIN = "example.com"

  belongs_to :user
  before_create :generate_cname

  attr_accessible :domain
  …

  # Validate unless already validated
  def validate!
    validate_cname unless self.verifed == true
  end

  protected

  # Generate a random string for cname
  def generate_cname
    chars = ('a'..'z').to_a
    self.cname = 10.times.collect { chars[rand(chars.length)] }.join
  end

  # Sets verifed to true if there is a CNAME record matching the cname attr and it points to this site.
  def validate_cname
    Resolv::DNS.open do |domain|
      @dns = domain.getresources("#{cname}.#{domain}", Resolv::DNS::Resource::IN::CNAME)
     self.verified = !@dns.empty? && @dns.first.name.to_s == YOUR_DOMAIN
    end
  end

end

Контроллер

class SitesController < ActionController::Base
  # Usual RESTful controller actions
  # …

  def validate
    @site = current_user.sites.find(params[:id])
    @site.validate!

    respond_to do |format|
      if @site.save && @site.verified
        flash[:notice] = 'Site verified!'
        format.html { redirect_to(@site) }
        format.xml  { head :ok }
      else
        flash[:Error] = 'Site verification failed!'
        format.html { redirect_to(@site) }
        format.xml  { render :status => :unprocessable_entity }
      end
    end

  end
end

Поместите это вways.rb:

map.resources :sites, :member => { :validate => :put }

Я оставлю реализацию представлений как упражнение для вас.

3 голосов
/ 03 декабря 2009

Вы можете подтвердить это способом, аналогичным тому, что делает Google Analytics, разместив на своем сайте некоторый javascript / код, который вы можете использовать для подтверждения. В качестве альтернативы вы можете попросить их создать DNS-запись, которую вы сможете проверить - обе они будут отображать фактическое владение сайтом, а не просто быть частью домена.

2 голосов
/ 04 декабря 2009

Инструменты сайта Google позволяют вам просто загрузить файл с очень конкретным именем. таким образом, вы можете потребовать, чтобы пользователь создал файл, чтобы вы могли убедиться, что он владеет веб-сайтом

require 'digest/sha1'
require 'net/http'

# you may want to store a unique value in the website table instead
unique_id = Digest::SHA1.hexdigest("#{website.id}/#{website.created_at}")
response = Net::HTTP.start(website.url, 80) {|http| http.head("/verify_#{unique_id}.html") }
website.verified = true if response.code == "200"
0 голосов
/ 05 декабря 2009

Большое спасибо, ребята. Я использовал смесь предложений Стива и Амиэль, чтобы найти решение, которое работает:

В модели сайта:

class Website < ActiveRecord::Base
  require 'net/http'

  belongs_to :user
  before_create :generate_unique_id

  # Validate unless already validated
  def verify!
    verify_unique_id unless self.verified == true
  end

  protected

  # Generate a random string for unique_id
  def generate_unique_id
    self.unique_id = ActiveSupport::SecureRandom.hex(10)
  end

  def verify_unique_id
  response = Net::HTTP.start(self.domain, 80) {|http| http.head("/#   {unique_id}.html") }
    self.verified = true if response.code == "200"
  end

end

Контроллер практически не изменился по предложению Стива, за исключением части, где приложение находит идентификатор веб-сайта:

    def verify
    @website = Website.find_by_id(params[:website])
    @website.verify!

    respond_to do |format|
      if @website.save && @website.verified == true
        flash[:notice] = 'Site verified!'
        format.html { redirect_to(websites_path) }
        format.xml  { head :ok }
      else
        flash[:notice] = 'Site verification failed!'
        format.html { redirect_to(websites_path) }
        format.xml  { render :status => :unprocessable_entity }
      end
    end
end

Наконец-то у меня есть индексное представление сайтов пользователя (это некрасиво, но оно выполняет свою работу):

<% for website in @websites %>
<%= link_to "#{website.domain}", website %> | 
<% if website.verified? %> VERIFIED |  
<% else %> NOT VERIFIED 
<%= link_to "Verify your website", verify_website_path(:website => website.id), :id => website.id %>
Verification key: <%= website.unique_id %>
<% end %><% end %>
<%= link_to "Add a website", new_website_path %>

В любом случае, я провел несколько ручных тестов на одном из моих существующих веб-сайтов, и он работает без проблем. Мне все еще, конечно, нужно выполнить другие проверки, но это было то, что мне действительно нужно помочь. Спасибо, ребята!

Kenji

0 голосов
/ 03 декабря 2009

Специальный код, встроенный в данную страницу (например, Google Analytics).

Вы также можете потребовать, чтобы пользователь указал URL в указанном домене с указанным контентом. Например, пользователь говорит, что по URL / vali / date / me в домене www.foo.com вы можете найти страницу, генерирующую текст " VALIDATED ".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...