0

是否可以根据用户登录(以用户为中心的路由)将 Rails 3 / 4 的用户路由限制到服务器完整网站?我大致考虑将不同的静态网站放在应用程序的子目录中,并让主根目录下的用户可以访问它们(通过登录保护)。

如果没有用户登录,则使用简单的登录掩码来识别用户,例如使用 devise。我正在考虑简化静态页面的暂存部署,例如使用中间人生成。最好有一个简单的 capistrano 任务来部署到 rails 应用程序,而不是创建子域、ftp 上传等。

在 / 下安装静态页面的原因是,大多数静态站点生成器都希望页面在 / 下,我想避免资产中的绝对/相对路径出现问题。

更加具体:

案例 1)用户未登录 -> 任何路由都要求进行身份验证

案例 2)用户已登录,静态内容从 /app/sites/site1 提供(安装在 "/" )

案例 3)另一个用户登录,静态内容从 /app/sites/site2 提供(安装在 "/" )

服务的网站取决于用户的个人资料。

4

1 回答 1

0

To anwer my own question: Yes it is possible.

In my case, Rails is not overkill. I have a seamless integration with our Rails-based project management system. I'm mounting a Sinatra-App as a web server, using a different public url based on user session. The session is generated via unique token, so that a user can view different static projects right after another.

routes.rb:

constraints(:subdomain => /preview/) do
    mount SinatraWrapper => "/"
end

Note: i'm using constrains here, to check subdomain. Every static preview is redirected to the same app, under a different subdomain.

Sinatra Wrapper:

# a super-trivial Sinatra-based webserver
# for static content
require 'sinatra/base'

class SinatraWrapper < Sinatra::Base
  before '/*' do
    SinatraWrapper.set_site(session[:site])
  end

  def self.set_site(site)
    rootPath = File.expand_path("#{Rails.root}/sites/#{site}/")
    set :public_folder, "#{rootPath}/current/build/"
  end

  configure do
    set :static, true
    set :static_cache_control, [:public, :no_store, :no_cache, :must_revalidate, :max_age => 0, :expires => "Fri, 01 Jan 1990 00:00:00 GMT"]
  end

  set_site("default")

  # route to starting page (index.html)
  get "/" do
    redirect "/index.html"
  end

  # route to custom error page (404.html)
  not_found do
    redirect "/404.html"
  end

end

Note: i'm deploying updates from static projects via capistrano right into the rails app. The build is performed remote via Middleman ( we could use any other static site generator here). Another instance checks our git repositories for updates in the "preview"-branch and run tests on it. After passing all tests, a build is performed and deployed automatically.

Here is the tricky bit, using different behaviour for two different subdomains, but same session:

# static_pages_controller.rb:

def preview

    if request.subdomain == "preview" or Rails.env.development? # local dev: no subdomains
      @static_page = StaticPage.find(params[:id])
      session[:site] = @static_page.slug || "default" # using a sha-slug for every static project
      redirect_to "/" # redirect to root. we have a valid session now.
    else
      # we are NOT on the preview subdomain, so we need to redirect to proper subdomain
      @project = Project.find(params[:project_id])
      @static_page = StaticPage.find(params[:id])
      redirect_to preview_url(project_id: @project.id, id: @static_page.id, token: @static_page.slug).sub("plattform", "preview")
    end
end

Note: I have projects with many many static pages. We have a preview action for every static page from the plattform. If you hit the preview action with a link from the plattform, you are redirected to the preview subdomain and your session is set. Our authentication allows us to

  • send anonymous links with authentication tokens (SHA-Slugs) to a customer
  • and authenticate via database

We use this system for half a year now and are very satisfied! The customer can see a preview right away. Until now, we have not encountered any serious problems, except that the caching headers must be set correctly to ensure that new content is loaded every time you reload the page. This slows down the experience, but we can always argument, that this is a preview. To be honest, most customers do not recognize the load times.

Anyway, i am not 100% sure if my implementation for "crashing" the cache is the perfect solution. Any hint would be very much appreciated. I only have problems in Chrome and Safari (very rare), where you need to reload the page several times until new content is shown.

Another interesting question is security. I think it is relatively safe. But i'm no security expert. Any concerns?

We use this platform only internally. No product, so we do not handle errors very gentle.

于 2014-07-30T10:12:30.863 回答