Validate website ownership in rails

前端 未结 5 1799
没有蜡笔的小新
没有蜡笔的小新 2021-01-14 10:17

For a more recent discussion about a similar topic check this question out.

What\'s the best way to validate whether a particular user has ownership of a website?

5条回答
  •  自闭症患者
    2021-01-14 11:00

    This is is how you could validate a domain using the google subdomain approach in a RESTful style. You will allow a user to create a Site record, which will remain unverified until the user later clicks a link/button to verify the domain at a later time (to allow DNS propagation).

    This code is untested but will get you started.

    Model:

    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
    

    Controller

    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
    

    Put this in routes.rb:

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

    I'll leave implementing the views as an exercise for you.

提交回复
热议问题