Chỉ làm việc này, nhưng chưa bao giờ thấy giải pháp đầu cuối.
Địa chỉ này điểm 3. 1 & 2 có thể dễ dàng thực hiện bằng cách đưa ra và ghi lại ở nơi khác.
Không quá khó để thêm auth FB vào ứng dụng web của bạn, hướng dẫn trên github cho omniauth và omniauth-facebook.
Tôi tin những điều sau đây là viết tắt một mình, mà không thực hiện tích hợp omniauth-facebook, nếu bạn muốn thực hiện theo cách đó. Điều này cũng tương tự như các cách tiếp cận khác. Ý tưởng của tôi là cố gắng sử dụng mô hình suy nghĩ kỹ càng nhất có thể.
Bạn sẽ cần đá quý fb_graph.
Trên máy khách di động, bạn xác thực với FB một cách thích hợp và đặt mã thông báo truy cập được trả về trong tiêu đề của các yêu cầu http của bạn. Tôi đã sử dụng tiêu đề fb_access_token. Cũng giống như auth cơ bản, bạn sẽ muốn gửi thông báo này qua SSL để tránh đánh hơi mã thông báo. Sử dụng tiêu đề cho phép tôi trao đổi auth cơ bản và xác thực FB mà không thay đổi yêu cầu, nhưng bạn có thể sử dụng tham số nếu bạn muốn.
Giải pháp này thực hiện một chiến lược bảo vệ dựa trên chiến lược bảo mật của Authenticatable. Sự khác biệt ở đây là thực tế rằng chiến lược này sử dụng một tiêu đề HTTP gọi là fb_access_token có chứa chuỗi mã thông báo truy cập facebook được truy xuất bằng ứng dụng di động.
Khi bạn biết điều này, mã này khá đơn giản.
Trong tệp, trong thư mục config/initializers, hãy thêm thông tin sau. Tôi tình cờ gọi tôi là fb_api_strategy.rb:
# authentication strategy to support API authentication over the webservice
# via facebook
require 'devise/strategies/database_authenticatable'
require 'fb_graph'
require 'warden'
module Devise
module Strategies
class FbMobileDatabaseAuthenticatable < Authenticatable
def valid?
# if we have headers with the facebook access key
!!request.headers["fb_access_token"]
end
def authenticate!
token = request.headers["fb_access_token"]
fbuser = FbGraph::User.me(token)
fbuser = fbuser.fetch
user = User.find_for_facebook_mobile_client(fbuser.email)
# this either creates a new user for the valid FB account, or attaches
# this session to an existing user that has the same email as the FB account
if !!user && validate(user) { true }
user.after_database_authentication
success!(user)
elsif !halted? || !user
fail(:invalid)
end
end
end
end
end
Warden::Strategies.add(:fb_database_authenticatable,
Devise::Strategies::FbMobileDatabaseAuthenticatable)
Trong config/initializers, thêm dòng sau vào devise.rb:
config.warden do |manager|
manager.default_strategies(:scope => :user).unshift :fb_database_authenticatable
end
Để cho phép bạn hoặc tạo một người dùng hoặc tìm một người dùng hiện dựa trên email FB, thêm sau đây để mô hình người dùng của bạn:
def self.find_for_facebook_mobile_client(fb_email)
if user = User.where(:email => fb_email).first
user
else
User.create!(:email => fb_email, :password => Devise.friendly_token[0,20])
end
end
tôi không nghĩ fb_database_authenticatable là một cái tên chính xác, nhưng tôi sẽ rời khỏi đó như là một bài tập cho người đọc. Một bài tập khác là lưu trữ bộ nhớ đệm/lưu trữ mã thông báo truy cập FB và có thể tránh RT đến FB với mỗi cuộc gọi. Bạn nên lưu ý rằng mã thông báo truy cập từ ứng dụng dành cho thiết bị di động và ứng dụng đường ray sẽ khác nếu bạn thực hiện xác thực FB trên cả hai mặt, điều mà tôi cho rằng hầu hết mọi người sẽ muốn thực hiện. Điều này có thể ảnh hưởng đến sơ đồ bộ nhớ đệm của bạn.
Tôi nghĩ điều đó - vui mã hóa.
Something cần lưu ý: Các quyền cơ bản cho việc sử dụng một tài khoản FB không cung cấp địa chỉ email. Bạn sẽ cần yêu cầu người dùng một cách rõ ràng về quyền này. – beeudoublez
Điểm tốt @beeudoublez, đó chính xác là những gì tôi đã làm trong ứng dụng của mình. – Matt