gpt4 book ai didi

ruby-on-rails - Omniauth facebook session Controller 在 Michael Hartl 教程之后创建 Action 集成

转载 作者:行者123 更新时间:2023-12-04 18:43:03 24 4
gpt4 key购买 nike

我刚刚完成了 Michael Hartl 教程。我正在尝试实现 omniauth-facebook 来注册和登录用户。我在创建要在 create 中使用的主变量时遇到问题 session Controller 中的操作。我的假设是我应该输入 if else查看主人是通过facebook还是通过默认表单登录的声明?或者我应该使用 and or陈述:

(master = Master.find_by(email: params[:session][:email].downcase) || Master.from_omniauth(env["omniauth.auth"])) ?

这是 omniauth-facebook sessons Controller 创建操作代码:
def create
user = User.from_omniauth(env["omniauth.auth"])
session[:user_id] = user.id
redirect_to root_url
end

这是我当前的 session Controller 创建操作代码:
class SessionsController < ApplicationController

def new
end

def create
master = Master.find_by(email: params[:session][:email].downcase)
if master && master.authenticate(params[:session][:password])
sign_in master
redirect_back_or master
else
flash.now[:error] = 'Invalid email/password combination'
render 'new'
end
end
.
.
.


end

最佳答案

虽然我可能会晚一年回答这个问题,但我仍然认为像一年前一样有同样问题的新观众可能会从以下答案中受益
据我了解,实际问题是:

How does one integrate Facebook Authentication with an Authentication system that is built from Scratch?


由于您说您使用了 Michael Hartl 的教程,因此我继续将我的答案改编为 Michael 自己编写的身份验证系统。现在让我们一步一步地检查每段代码。

1
首先,我们需要为 的现有用户表创建两个额外的列。供应商用户名如下... rails g migration add_facebook_auth_to_users provider uid...并将 omniauth-facebook gem 添加到 Gemfile ...
Gemfile gem 'omniauth-facebook', '2.0.1'不要忘记运行 bundle install并在之后迁移您的数据库。

2
接下来我们需要继续编辑我们的 Sessions Controller ......
session_controller.rb
def create
user = User.find_by(email: params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
if user.activated?
log_in user
params[:session][:remember_me] == '1' ? remember(user) : forget(user)
redirect_back_or user
else
message = "Account not activated. "
message += "Check your email for the activation link."
flash[:warning] = message
redirect_to root_url
end
else
flash.now[:danger] = 'Invalid email/password combination'
render 'new'
end
end

def create_facebook
user = User.from_omniauth(env["omniauth.auth"])
log_in user
redirect_back_or user
end
上面的 session Controller 包含两个创建操作。第一个是直接取自书中的原始方法,第二个是我专门用于 Facebook 身份验证的一段代码。
专线 user = User.from_omniauth(env["omniauth.auth"])有两个目的。创建用户 如果 他/她唯一的 facebook uid 不在数据库中 其他 如果 uid 存在,则在应用程序中记录此人。稍后会详细介绍。

3
接下来让我们创建一个工作 .from_omniauth 您在问题中的代码中简要显示的方法...
user.rb
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_initialize.tap do |user|
user.provider = auth.provider
user.uid = auth.uid
user.name = auth.info.name unless user.name != nil
user.email = SecureRandom.hex + '@example.com' unless user.email != nil
user.activated = true
user.password = SecureRandom.urlsafe_base64 unless user.password != nil
user.save!
end
end
在这里,我们尝试找到与给定 provider 匹配的用户和 uid来自散列的值,然后我们调用 first_or_initialize在这个结果上。这个方法要么返回第一个匹配的记录,要么用传入的参数初始化一个新记录。然后我们调用 tap在此将该 User 实例传递给块。在块内,我们根据来自 OmniAuth 哈希的值设置用户的各种属性。
你可能对我为什么把 unless 感兴趣一些属性初始化之后的语句。那么考虑一下用户想要更新配置文件的情况,比如更改名称或 smth,然后注销。当该用户最终决定重新登录时, .from_omniauth方法将覆盖用户有问题的更新到原始 facebook 值, 除非 我们阻止它这样做。
另请注意 SecureRandom 的使用图书馆。在 Michael Hartl 在其书中使用的传统身份验证中,他介绍了对电子邮件和密码提交的验证。电子邮件既不能是空白也不能被占用。同样,密码的长度必须大于 6 个字符。由于电子邮件必须存在且独一无二,我决定创建 假人使用 SecureRandom.hex + @example.com 的电子邮件.这将创建一个随机的十六进制字符串,如 52750b30ffbc7de3b362 ,并将其附加到 @example.com ,从而生成唯一的虚拟电子邮件。密码也是如此,但是,我更喜欢使用 SecureRandom.urlsafe_base64 生成一个随机的 base64 字符串。 .要记住的最重要的事情是 Facebook 用户不需要知道这些信息即可登录,因为这是使用 Facebook 身份验证的全部意义所在。如果他们愿意,这允许他们稍后将这些信息与真实数据一起添加。

4
现在是在主应用程序页面上为用户添加按钮以让他们实际登录应用程序的好时机......
_header.html.erb
<% if logged_in? %>
.
.
.
<% else %>
.
.
<li><%= link_to "Sign in with Facebook", "/auth/facebook", id: "sign_in" %></li>
<% end %>

5
所以,现在我们可以向 facebook 发送请求。一个问题仍然是我们实际上无法处理回调。为此,我们需要执行以下操作...
  • 添加 get 'auth/:provider/callback' => 'sessions#create_facebook'路线.rb 文件
  • 使用 Facebook 提供的方便的 Javascript SDK。让我们创建一个使用此 SDK 的自定义 javascript 文件...

  • 应用程序/ Assets /javascripts/facebook.js.erb
    jQuery(function() {
    $('body').prepend('<div id="fb-root"></div>');
    return $.ajax({
    url: window.location.protocol + "//connect.facebook.net/en_US/sdk.js",
    dataType: 'script',
    cache: true
    });
    });

    window.fbAsyncInit = function() {
    FB.init({
    appId: 'your_facebook_app_id_goes_here',
    version: 'v2.3',
    cookie: true
    });
    $('#sign_in').click(function(e) {
    e.preventDefault();
    return FB.login(function(response) {
    if (response.authResponse) {
    return window.location = '/auth/facebook/callback';
    }
    });
    });
    return $('#sign_out').click(function(e) {
    FB.getLoginStatus(function(response) {
    if (response.authResponse) {
    return FB.logout();
    }
    });
    return true;
    });
    };

    6
    就是这样,除了一个小小的警告......
    problem
    如果用户决定去编辑个人资料,他/她会看到我们的虚拟电子邮件显示在中间。这是因为 Rails 足够聪明,可以自动填充用户的信息。坦率地说,在这种情况下,这很尴尬。然而,好消息是它很容易修复。只需将表单内的值设置为 nil ,就像这样...... <%= f.email_field :email, value: nil, class: 'form-control' %>
    希望这可以帮助那些想要从头开始构建身份验证系统的人:)

    关于ruby-on-rails - Omniauth facebook session Controller 在 Michael Hartl 教程之后创建 Action 集成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20719735/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com