混淆 URL - rails

Obfuscation of URLs - rails

我正在做一个让我感到困惑的项目,希望有人能提供一些有趣的意见。我看到有几个 gems 可用于混淆 url,但它们似乎停止在 slug 级别而不是控制器级别 - 即 www.foo.com/mycontroller/8sZ16lp。我正在寻找一种方法来生成类似于 www.foo.com/8asd31Ud 的内容,删除控制器名称。我检查了 obsufacate_id gem 的文档,但它似乎并没有走那么远。

提供更多背景信息 - 我真的很希望 www.foo.com/mycontroller/15/edit = www.foo.com/95Ali32

因为这不符合 rails RESTful URL 的惯例,我猜你可能只需要编写自己的路线,也许更多。出于好奇,您如何设想系统知道要使用“95Ali32”加载什么类型的对象?这可能更好地使用 Sinatra 或其他可以让您更好地控制路由和更少约定的东西。

这是一种可能的方法,它使用 table 和映射到类型和对象 ID 的 slug:

# migration
create_table :slugs do |t|
  t.string :object_type, :null => false
  t.string :object_id, :null => false
  t.string :slug
  t.timestamps
end

# models
class Slugs < ActiveRecord::Base
  belongs_to :object, :polymorhic => true
end

class AModel < ActiveRecord::Base
  has_one :slug, :as => :owner
end

# routes.rb
# note that anything else should go above this because this will catch all other URL's
get '*slug', to: 'slugs#show'

# controller
class SlugsController < ApplicationController
  def show
    @object = Slug.where(slug: params[:slug])
    raise ActiveRecord::NotFound.new unless @object
    render @object.kind
  end
end

然后您需要为每种类型的对象构建视图。参见 this related question


更新

这是另一个想法。你需要这个 slug 有多晦涩?如果每个模型都有一个已知代码然后 ID 以某种方式编码并附加到模型代码会怎样?然后你可以使用预先配置的路由在代码中做一些更简单的事情:

# You could generate this too, or just hard-code them
prefixes = ['8sZ', '95Ali']
[:a_model, :another_model].each do |model|
  match "#{prefixes.pop}:id", :controller => model.to_s.underscore.pluralize, :action => :show, :as => model
end 

这会给你这样的路线

/8sZ1 #=> AModelsController#show(:id => 1)
/95Ali341 #=> AModelsController#show(:id => 341)

您可以更进一步,使用 friendly_id 为模型 ID 生成 slug。或者使用 UUID 而不是整数 ID(PostgreSQL 支持)。