如何使我的RESTful show动作显示令牌而不是ID

时间:2016-09-12 18:32:16

标签: ruby ruby-on-rails-4 rubygems

我创建了一个使用Ruby on Rails的网站,我认为它很容易被抓,因为ID显示在URL中。

当我点击我的控制器中show-action管理的每位律师时,RESTful网址会显示http://localhost:3000/lawyers/1。在这种情况下,1是我律师桌上律师的身份证。

  

问题:

     

在查看特定条目时,如何显示令牌而不是id   与表演行动?这样我就像http://localhost:3000/lawyers/92a5e084-d660-41a7-98d7-cb8075797591

注意

律师桌上的每位律师都有一个独特的标记。

以下是我的代码:

lawyers_controller.rb

class LawyersController < ApplicationController

  before_action :get_lawyer, only: [:show, :edit, :preview, :destroy]


  def show
    respond_to do |format|
      format.html # show.html.erb
      format.json {render json: @lawyer }
      format.xml {render xml: @lawyer }
    end
  end


  private

  def get_lawyer
    @lawyer = Lawyer.find(params[:id])
  end


  def law_params
    params.require(:lawyer).permit(:name, :category_id,
                                   :image, :title, :category_id,
                                   :phone_number, :website, :email,
                                   :twitter_link, :linkedin_link,
                                   :professional_details, :published,
                                   :token, :remove_image )
  end

end

route.rb

Rails.application.routes.draw do

  mount RedactorRails::Engine => '/redactor_rails'
  root 'lawyers#index'


  resources :lawyers, except: [:index, :new]
  get 'lawyers/:id/preview' => 'lawyers#preview', as: :preview_lawyer
  get 'new' => 'lawyers#new', as: :new
end

lawyer.rb

class Lawyer < ActiveRecord::Base
  belongs_to :category

  mount_uploader :image, ImageUploader

  validates :image,
            :name,
            :title,
            :category_id,
            :website,
            :email,
            presence: true
  validates :professional_details, length: { minimum: 300 }
  #validates :website, format: URI::regexp(%w(http https))

  validates_formatting_of :email, using: :email

  before_create :add_token
  before_save :format_lawyer_url



  def its_published?
    (!(self.published == nil))
  end


  private

  def add_token
    self.token = SecureRandom.uuid
  end

  def format_lawyer_url
    unless website =~ URI::regexp(%w(http https))
      add_http_prefix
    end
  end

  def add_http_prefix
    if website
      self.website = "http://#{self.website}"
    end
  end
end

schema.rb

ActiveRecord::Schema.define(version: 20160909121118) do

  create_table "categories", force: :cascade do |t|
    t.string   "name"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.integer  "parent_id"
  end

  create_table "lawyers", force: :cascade do |t|
    t.string   "name"
    t.string   "image"
    t.string   "title"
    t.string   "email",                default: "", null: false
    t.integer  "phone_number"
    t.text     "professional_details"
    t.string   "website"
    t.string   "twitter_link"
    t.string   "linkedin_link"
    t.datetime "created_at",                        null: false
    t.datetime "updated_at",                        null: false
    t.integer  "category_id"
    t.string   "token"
    t.boolean  "published"
  end

  add_index "lawyers", ["category_id"], name: "index_lawyers_on_category_id"
  add_index "lawyers", ["email"], name: "index_lawyers_on_email"
  add_index "lawyers", ["name"], name: "index_lawyers_on_name"
  add_index "lawyers", ["phone_number"], name: "index_lawyers_on_phone_number"
  add_index "lawyers", ["published"], name: "index_lawyers_on_published"
  add_index "lawyers", ["token"], name: "index_lawyers_on_token"
end

注意:根据以下评论的建议,我尝试过在那里发布的解决方案。即Route Post#TOKEN instead of Post#ID in rails,但我不会同意。

为什么?

  1. 这使我的代码容易出错。
  2. 我的兴趣只是在我的节目动作上显示token,而不是id
  3. 建议我覆盖模型中的to_param方法的最后一个答案,使用此方法:

    def to_param
      "#{id}-#{token}"
    end
    

    但仍然没有让我的代码不易被Scrappers解析。 任何技术娴熟的人都可以轻松复制数据库表,因为它仍然会添加id

1 个答案:

答案 0 :(得分:0)

这就是我用来解决问题的方法:

在我的模型中,我覆盖了to_param方法,以便将其附加到token

  def to_param # overridden
    token
  end

当我访问NoMethodError in Lawyers#show这样的易受攻击的网址时,http://localhost:3000/lawyers/7仍然存在一个棘手的错误,QueryInterface对应于显示身份为7的律师。

我使用这个Railscast修改后的视频后有一个更好的解决方案: https://www.youtube.com/watch?v=963wTp9FCn4