2010-08-13 40 views
56

Chúng tôi sẽ phát triển một ứng dụng API nhỏ ở Sinatra. Các tùy chọn xác thực có sẵn để bảo mật các cuộc gọi API là gì?Sinatra - API - Xác thực

Trả lời

88

Sinatra không có hỗ trợ xác thực được tích hợp sẵn. Có một số đá quý có sẵn, nhưng hầu hết được thiết kế để xác thực người dùng (ví dụ: đối với trang web). Đối với một API, họ có vẻ như quá mức cần thiết. Thật dễ dàng để tự làm. Chỉ cần kiểm tra các thông số yêu cầu trong mỗi tuyến đường của bạn để xem liệu chúng có chứa khóa API hợp lệ hay không và nếu không, hãy trả lại lỗi 401.

helpers do 
    def valid_key? (key) 
    false 
    end 
end 

get "/" do 
    error 401 unless valid_key?(params[:key]) 

    "Hello, world." 
end 

# $ irb -r open-uri 
# >> open("http://yourapp.com/api/?key=123") 
# OpenURI::HTTPError: 401 Unauthorized 

Không có gì sau khi cuộc gọi đến error sẽ xảy ra nếu phương pháp valid_key? của bạn trả về false - error gọi halt trong nội bộ, mà dừng lại các yêu cầu từ tiếp tục.

Tất nhiên, không phải lý tưởng để lặp lại séc ở đầu mỗi tuyến đường. Thay vào đó, bạn có thể tạo tiện ích nhỏ có thêm điều kiện để các tuyến đường của bạn:

class App < Sinatra::Base 
    register do 
    def check (name) 
     condition do 
     error 401 unless send(name) == true 
     end 
    end 
    end 

    helpers do 
    def valid_key? 
     params[:key].to_i % 2 > 0 
    end 
    end 

    get "/", :check => :valid_key? do 
    [1, 2, 3].to_json 
    end 
end 

Nếu bạn chỉ muốn xác thực trên tất cả các tuyến đường của bạn, sử dụng một handler before:

before do 
    error 401 unless params[:key] =~ /^xyz/ 
end 

get "/" do 
    {"e" => mc**2}.to_json 
end 
+7

Todd Yandell, cảm ơn rất nhiều câu trả lời chi tiết và thời gian bạn dành cho nó. Tôi thực sự đánh giá cao. Nó thực sự hữu ích. Imran – Saim

+0

Tạo tiện ích mở rộng nhỏ có vẻ quá mức, bộ lọc trước là đủ, vì tùy chọn sau có tùy chọn áp dụng cho các tuyến đường nào. Bạn cũng có thể nói rằng từ bên trong phần thân của bộ lọc theo request.path_info. – Robert

2

http://www.secondforge.com/blog/2014/11/05/simple-api-authentication-in-sinatra/ có một chút chi tiết hơn câu trả lời sử dụng mã thông báo người dùng.

Đây là một bước phức tạp hơn khóa API nhưng cần thiết nếu API của bạn cần xác thực để đăng nhập người dùng thực hiện những việc như chỉnh sửa tên/email/mật khẩu hoặc truy cập thông tin cho mỗi người dùng. (tức là các hành động API "riêng tư"). Bạn cũng có thể hủy bỏ/hết hạn thẻ dùng để cho mọi người thoát ra vv

class App < Sinatra::Base 

    before do 
    begin 
     if request.body.read(1) 
     request.body.rewind 
     @request_payload = JSON.parse request.body.read, { symbolize_names: true } 
     end 
    rescue JSON::ParserError => e 
     request.body.rewind 
     puts "The body #{request.body.read} was not JSON" 
    end 
    end 

    post '/login' do 
    params = @request_payload[:user] 

    user = User.find(email: params[:email]) 
    if user.password == params[:password] #compare the hash to the string; magic 
     #log the user in 
    else 
     #tell the user they aren't logged in 
    end 
    end 
end 

(Đó là giá trị cần lưu ý rằng nó phổ biến hơn để đọc thông tin từ một tiêu đề HTTP thay vì cơ thể JSON, nhưng tác giả đề cập rằng .)

Các vấn đề liên quan