我创建了一个使用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,但我不会同意。
为什么?
token
,而不是id
。建议我覆盖模型中的to_param方法的最后一个答案,使用此方法:
def to_param
"#{id}-#{token}"
end
但仍然没有让我的代码不易被Scrappers解析。
任何技术娴熟的人都可以轻松复制数据库表,因为它仍然会添加id
。
答案 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