Trong trường hợp cụ thể của bạn, bạn có thể nghĩ rằng lập mưu cho phép ứng dụng của bạn để xác thực người dùng sử dụng một hình thức (ví dụ: bằng cách sử dụng một email và mật khẩu) hoặc mã thông báo xác thực, Omniauth cho phép ứng dụng của bạn "nói" với máy chủ Facebook để xác thực người dùng. Nói cách khác, Omniauth nằm trên đầu trang của Devise và mở rộng số cách người dùng của bạn có thể xác thực.
Thực hiện Facebook đăng nhập bạn cần phải:
0) configure devise: chỉ cần làm theo này: https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview
1) tiếp xúc với một liên kết trong quan điểm của bạn mà khi nhấn vào bởi người sử dụng sẽ cho Omniauth để bắt đầu " nói "với máy chủ Facebook.
=link_to image_tag("facebook_64.png", :size => "64x64", :alt => "Facebook"), user_omniauth_authorize_path(:facebook, :display=>"dialog"), :title=>"Facebook"
2) Tại một thời điểm máy chủ Facebook sẽ gọi cho bạn ứng dụng vì vậy bạn phải thực hiện một bộ điều khiển để đáp ứng với Facebook
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
before_filter { @omniauth_hash = env["omniauth.auth"] }
# This method is responsible to create a registration_hash given an
# omniaauth_hash
# schama: https://github.com/intridea/omniauth/wiki/Auth-Hash-Schema
def self.build_registration_hash(omniauth_hash={})
if (omniauth_hash["provider"].downcase.eql?("facebook"))
provider = "facebook"
# catch any excpetions thrown by code just to make sure we can continue even if parts of the omnia_has are missing
begin
first_name = omniauth_hash['user_info']['first_name']
last_name = omniauth_hash['user_info']['last_name']
sex = omniauth_hash.fetch('extra', {}).fetch('user_hash',{})['gender']
birthday = Date.strptime(omniauth_hash.fetch('extra', {}).fetch('user_hash', {})['birthday'],'%m/%d/%Y') if omniauth_hash.fetch('extra', {}).fetch('user_hash', {})['birthday']
if omniauth_hash.fetch('extra', {}).fetch('user_hash', {})['timezone']
utc_offset_in_hours = (omniauth_hash.fetch('extra', {}).fetch('user_hash', {})['timezone']).to_i
time_zone = (ActiveSupport::TimeZone[utc_offset_in_hours]).name
else
time_zone = nil
end
locale = omniauth_hash.fetch('extra', {}).fetch('user_hash', {})['locale']
home_town = omniauth_hash.fetch('extra', {}).fetch('user_hash', {}).fetch('location', {})['name']
if omniauth_hash.fetch('user_info', {})['image']
photo_url = (omniauth_hash.fetch('user_info', {})['image']).gsub("=square","=large") #http://graph.facebook.com/531564247/picture?type=square
else
photo_url = nil
end
rescue => ex
logger.error("Error while parsing facebook auth hash: #{ex.class}: #{ex.message}")
sex = nil
birthday = nil
time_zone = nil
locale = nil
home_town = nil
photo_url = nil
end
elsif omniauth_hash['uid'].downcase.include?("google.com")
provider = "google"
if omniauth_hash['user_info']['first_name'] and omniauth_hash['user_info']['last_name']
first_name = omniauth_hash['user_info']['first_name']
last_name = omniauth_hash['user_info']['last_name']
elsif omniauth_hash['user_info']['name']
first_name = omniauth_hash['user_info']['name'].split(' ')[0]
last_name = omniauth_hash['user_info']['name'].split(' ')[1]
else
first_name = nil
last_name = nil
end
sex = nil
birthday = nil
time_zone = nil
locale = nil
home_town = nil
photo_url = nil
elsif omniauth_hash['uid'].downcase.include?("yahoo.com")
provider = "yahoo"
if omniauth_hash['user_info']['first_name'] and omniauth_hash['user_info']['last_name']
first_name = omniauth_hash['user_info']['first_name']
last_name = omniauth_hash['user_info']['last_name']
elsif omniauth_hash['user_info']['name']
first_name = omniauth_hash['user_info']['name'].split(' ')[0]
last_name = omniauth_hash['user_info']['name'].split(' ')[1]
else
first_name = nil
last_name = nil
end
sex = nil
birthday = nil
time_zone = nil
locale = nil
home_town = nil
photo_url = nil
elsif omniauth_hash['uid'].downcase.include?("aol.com")
if omniauth_hash['user_info']['first_name'] and omniauth_hash['user_info']['last_name']
first_name = omniauth_hash['user_info']['first_name']
last_name = omniauth_hash['user_info']['last_name']
elsif omniauth_hash['user_info']['name']
first_name = omniauth_hash['user_info']['name'].split(' ')[0]
last_name = omniauth_hash['user_info']['name'].split(' ')[1]
else
first_name = nil
last_name = nil
end
provider = "aol"
sex = nil
birthday = nil
time_zone = nil
locale = nil
home_town = nil
photo_url = nil
else
provider = "open_id"
if omniauth_hash['user_info']['first_name'] and omniauth_hash['user_info']['last_name']
first_name = omniauth_hash['user_info']['first_name']
last_name = omniauth_hash['user_info']['last_name']
elsif omniauth_hash['user_info']['name']
first_name = omniauth_hash['user_info']['name'].split(' ')[0]
last_name = omniauth_hash['user_info']['name'].split(' ')[1]
else
first_name = nil
last_name = nil
end
sex = nil
birthday = nil
time_zone = nil
locale = nil
home_town = nil
photo_url = nil
end
h = {
:provider => provider,
:email => omniauth_hash['user_info']['email'],
:profile_attributes => {
:first_name => first_name ,
:last_name => last_name,
:avatar_url => photo_url,
:sex => sex,
:birthday => birthday,
:time_zone => time_zone,
:locale => locale,
:location => home_town
}
}
end
def process_callback
# The registration hash isolates the rest of the code from learning all the different structures
# of the omnia_hash
registration_hash = Users::OmniauthCallbacksController.build_registration_hash(@omniauth_hash)
logger.debug(registration_hash.to_yaml)
# Set the @user to nil
@user = nil
# Find if an authentication token for this provider and user id already exists
authentication = Authentication.find_by_provider_and_uid(@omniauth_hash['provider'], @omniauth_hash['uid'])
if authentication # We found an authentication
if user_signed_in? && (authentication.user.id != current_user.id)
flash[:error] = I18n.t "controllers.omniauth_callbacks.process_callback.error.account_already_taken",
:provider => registration_hash[:provider].capitalize,
:account => registration_hash[:email]
redirect_to edit_user_account_path(current_user)
return
end
else
# We could not find the authentication than create one
authentication = Authentication.new(:provider => @omniauth_hash['provider'], :uid => @omniauth_hash['uid'])
if user_signed_in?
authentication.user = current_user
else
registration_hash[:skip_confirmation] = true
authentication.user = User.find_by_email(registration_hash[:email]) || User.create_user(registration_hash)
end
end
@user = authentication.user
# save the authentication
authentication.token = @omniauth_hash
authentication.provider_name = registration_hash[:provider]
authentication.provider_username = registration_hash[:email]
if !authentication.save
logger.error(authentication.errors)
end
# If a user is signed in then he is trying to link a new account
if user_signed_in?
if authentication.persisted? # This was a linking operation so send back the user to the account edit page
flash[:success] = I18n.t "controllers.omniauth_callbacks.process_callback.success.link_account",
:provider => registration_hash[:provider].capitalize,
:account => registration_hash[:email]
else
flash[:error] = I18n.t "controllers.omniauth_callbacks.process_callback.error.link_account",
:provider => registration_hash[:provider].capitalize,
:account => registration_hash[:email],
:errors =>authentication.errors
end
redirect_to edit_user_account_path(current_user)
else
# This was a sign in operation so sign in the user and redirect it to his home page
if @user.persisted? && authentication.persisted?
flash[:success] = I18n.t "controllers.omniauth_callbacks.process_callback.success.sign_in",
:provider => registration_hash[:provider].capitalize,
:account => registration_hash[:email]
sign_in_and_redirect(:user,@user)
else
session['registration_hash'] = registration_hash
flash[:error] = I18n.t "controllers.omniauth_callbacks.process_callback.error.sign_in",
:provider => registration_hash[:provider].capitalize,
:account => registration_hash[:email]
redirect_to new_registration_users_url
end
end
end
def facebook
process_callback
end
def gmail
process_callback
end
Bây giờ bạn sẽ thấy rằng tôi gọi một User.create_user (registration_hash). thực hiện phương pháp này sẽ phụ thuộc vào cách ứng dụng của bạn tạo một người dùng nhưng đồng tối thiểu phương pháp này phải tạo một người dùng và gán cho nó một mật khẩu ngẫu nhiên:
def self.create_user(registration_hash)
logger.info "Creating new user with registration hash: #{registration_hash.to_yaml}"
unless registration_hash or resigration_hash.empty?
return nil
end
user = User.new
user.email = registration_hash[:email]
if registration_hash[:password]
user.password = registration_hash[:password]
else
user.password = Devise.friendly_token[0,20]
end
user.password_confirmation = user.password
# custom app code here...
if registration_hash[:skip_confirmation] == true
user.confirm!
end
user
end
Lưu ý: My hỗ trợ ứng dụng đăng nhập với dịch vụ khác vì vậy tôi có đã triển khai bảng chứa mã thông báo xác thực.
Hy vọng điều này có thể giúp bạn bắt đầu.
Tùy chọn 'thoại' dường như bị phản đối. Tôi nghĩ 'popup' tương đương với những ngày này. – drewww
Bây giờ, Popup cũng được khấu hao @drewww –