2010-09-03 30 views
28

Tôi đang nâng cấp một ứng dụng lên Rails 3.0.0 và tự hỏi liệu phương pháp chuẩn để thêm SSL có thay đổi không (tôi mơ hồ nhớ các bản demo cho biết bộ định tuyến có thể xử lý SSL, mặc dù tôi không chắc chắn chỉ dành cho mục đích trình diễn). Tôi hiện đang sử dụng đá quý "ssl_requirement", tuy nhiên nó cung cấp:Rails 3 SSL Deprecation

DEPRECATION CẢNH BÁO: Việc sử dụng #request_uri không được dùng nữa. Thay vào đó hãy sử dụng fullpath. (Gọi từ ensure_proper_protocol tại /Library/Ruby/Gems/1.8/gems/ssl_requirement-0.1.0/lib/ssl_requirement.rb:53)

Ngoài ra, nó xuất hiện để phá vỡ khi xử lý mới 'dữ liệu phương pháp ' thuộc tính. Ví dụ:

<%= link_to "Logout", user_path, :method => :delete %> 

Hoạt động tốt khi truy cập từ một phần SSL của ứng dụng, nhưng thất bại (cố gắng để làm cho chương trình hành động) khi tiếp từ một bộ phận không SSL (tất cả các hành động trong bộ điều khiển người dùng yêu cầu SSL, mặc dù Tôi hiểu rằng hành động phá hủy không truyền dữ liệu an toàn).

Trả lời

46

Đó là thực sự khá đơn giản trong Rails 3. Trong config/routes.rb:

MyApplication::Application.routes.draw do 
    resources :sessions, :constraints => { :protocol => "https" } 
end 

Hoặc nếu bạn cần để buộc SSL cho nhiều tuyến đường:

MyApplication::Application.routes.draw do 
    scope :constraints => { :protocol => "https" } do 
    # All your SSL routes. 
    end 
end 

Và liên kết với các tuyến đường SSL có thể được thực hiện như thế này :

<%= link_to "Logout", sessions_url(:protocol => 'https'), :method => :delete %> 

Nếu bạn muốn tự động chuyển hướng một số bộ điều khiển (hoặc thực sự, một số subpath) đến một URL https dựa trên tương đương, bạn có thể thêm một cái gì đó như thế này để các tuyến đường của bạn (Tôi muốn phần này là đơn giản):

# Redirect /foos and anything starting with /foos/ to https. 
match "foos(/*path)", :to => redirect { |_, request| 
    "https://" + request.host_with_port + request.fullpath } 
+1

Điều này có vẻ phức tạp hơn việc sử dụng 'ssl_requirement'. Có phải phương pháp tiêu chuẩn mới để thực hiện nó trong Rails 3 hay là 'ssl_requirement' vẫn có thể sử dụng được không? Cảm ơn. –

+1

@Kevin: Ngoài việc chuyển hướng tự động, tôi nghĩ nó khá dễ dàng. Hơn nữa, điều này là hoàn toàn có thể với DSL * tiêu chuẩn * định tuyến, một cái gì đó không thể được thực hiện trong Rails 2, do đó sự cần thiết cho một thư viện bên ngoài. – molf

+4

Trong môi trường phát triển, hãy thực hiện phạm vi: ràng buộc => {: protocol => Rails.env.production? ? 'https': 'http'} làm ... kết thúc Nguồn: http://www.themomorohoax.com/2010/10/08/using-ssl-in-rails-3 – mysmallidea

20

Sau khi trải qua một buổi chiều tìm kiếm các giải pháp tốt nhất mà tôi giải quyết trên phương pháp tiếp cận được mô tả trong bài viết này: http://clearcove.ca/blog/2010/11/how-to-secure-a-rails-app-on-heroku-with-ssl-firesheep/ mà tham chiếu bài viết này: Force SSL using ssl_requirement in Rails 2 app

về cơ bản làm điều này:

# lib/middleware/force_ssl.rb 
class ForceSSL 
    def initialize(app) 
    @app = app 
    end 

    def call(env) 
    if env['HTTPS'] == 'on' || env['HTTP_X_FORWARDED_PROTO'] == 'https' 
     @app.call(env) 
    else 
     req = Rack::Request.new(env) 
     [301, { "Location" => req.url.gsub(/^http:/, "https:") }, []] 
    end 
    end 
end 

# config/application.rb 
config.autoload_paths += %W(#{ config.root }/lib/middleware) 

# config/environments/production.rb 
config.middleware.use "ForceSSL" 
+1

Tôi thích phương pháp này vì giải pháp của @ molf yêu cầu SSL ngay cả trong môi trường phát triển. –

14

Toppic là cũ nhưng chỉ dành riêng cho googling người:

trong * app/controller/your_controller.rb *

class LostPasswordsController < ApplicationController 

    force_ssl 

    def index 
    #.... 
    end 
end 

nếu trên toàn cầu sử dụng nó trong điều khiển ứng dụng

http://apidock.com/rails/ActionController/ForceSSL/ClassMethods/force_ssl

... thx SL cho tip

+0

Cảm ơn vì điều này. Kết hợp với các tùy chọn 'except' và' only', đây là một giải pháp tuyệt vời cho SSL chọn lọc. – LouieGeetoo

+1

đường ray 3.1 chỉ mặc dù –

+0

b.t.w. có một differennce giữa 'config.force_ssl' và controller' force_ssl' http://www.eq8.eu/blogs/14-config-force_ssl-is-different-than-controller-force_ssl – equivalent8

1

Trong Rails sau (ít nhất là 3.12+), bạn có thể sử dụng sau đây, môi trường cụ thể:

trong config/môi trường/production.rb (hoặc môi trường khác)

# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 
config.force_ssl = true