使用基于用户会话的Rails服务静态网站

时间:2013-06-19 11:27:21

标签: ruby-on-rails

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

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

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

更具体一点:

案例1)用户未登录 - >任何路线要求认证

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

案例3)其他用户已登录,静态内容从/ app / sites / site2(安装在“/”)提供

所投放的网站取决于用户资料。

1 个答案:

答案 0 :(得分:0)

提出我自己的问题:是的,这是可能的。

就我而言,Rails并不过分。我与基于Rails的项目管理系统无缝集成。我正在安装一个Sinatra - App作为Web服务器,使用基于用户会话的不同公共URL。会话通过唯一令牌生成,以便用户可以一个接一个地查看不同的静态项目。

routes.rb中:

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

注意:我在这里使用约束来检查子域。每个静态预览都会重定向到同一个应用程序,位于不同的子域下。

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

注意:我正在通过capistrano将静态项目的更新部署到rails应用程序中。构建是通过Middleman远程执行的(我们可以在这里使用任何其他静态站点生成器)。另一个实例检查我们的git存储库以获取“预览”-branch中的更新并对其进行运行测试。通过所有测试后,将自动执行构建并进行部署。

这是一个棘手的问题,对两个不同的子域使用不同的行为,但同一个会话:

# 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

注意:我的项目有很多静态页面。我们对平台上的每个静态页面都有预览操作。如果您使用平台中的链接点击预览操作,则会重定向到预览子域并设置会话。我们的身份验证允许我们

  • 向客户发送带有身份验证令牌(SHA-Slugs)的匿名链接
  • 并通过数据库进行身份验证

现在使用这个系统半年,非常满意!客户可以立即看到预览。到目前为止,我们没有遇到任何严重的问题,除了必须正确设置缓存标头以确保每次重新加载页面时都加载新内容。这会减慢体验,但我们总是可以争论,这是预览。说实话,大多数客户都不承认加载时间。

无论如何,我不是100%确定我的“崩溃”缓存是否是完美的解决方案。任何提示都将非常感激。我只在Chrome和Safari中遇到问题(非常罕见),您需要多次重新加载页面,直到显示新内容。

另一个有趣的问题是安全性。我认为它相对安全。但我不是安全专家。有什么顾虑吗?

我们仅在内部使用此平台。没有产品,所以我们不会非常温和地处理错误。