加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails – Omniauth facebook会话控制器在Michael Hartl

发布时间:2020-12-17 03:23:30 所属栏目:百科 来源:网络整理
导读:我刚刚完成了Michael Hartl教程.我正在尝试实施omniauth-facebook注册和登录用户.我在创建要在会话控制器中的创建操作中使用的主变量时遇到问题.我的假设是我应该在if else声明中查看主人是通过Facebook登录还是通过默认表格登录?或者我应该使用和/或声明:
我刚刚完成了Michael Hartl教程.我正在尝试实施omniauth-facebook注册和登录用户.我在创建要在会话控制器中的创建操作中使用的主变量时遇到问题.我的假设是我应该在if else声明中查看主人是通过Facebook登录还是通过默认表格登录?或者我应该使用和/或声明:

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

这是omniauth-facebook sessons控制器创建动作代码:

def create
    user = User.from_omniauth(env["omniauth.auth"])
    session[:user_id] = user.id
    redirect_to root_url
  end

这是我当前的会话控制器创建动作代码:

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?

既然你说过你使用过迈克尔·哈特尔的教程,我就继续调整了迈克尔自己编写的认证系统的答案.现在让我们一步一步地遍历每一段代码.

1

首先,我们需要为现有的Users表创建两个额外的列,用于提供者和uid,如下所示……

rails g migration add_facebook_auth_to_users provider uid

…并在Gemfile中添加omniauth-facebook gem …

的Gemfile

gem’omniauth-facebook’,’2.0.1′

不要忘记运行bundle install并在之后迁移数据库.

2

接下来我们需要继续编辑我们的Sessions控制器……

sessions_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

上面的会话控制器包含两个创建操作.第一个是直接从书中获取的未触及的方法,第二个是我专门用于Facebook身份验证的一段代码.

行user = User.from_omniauth(env [“omniauth.auth”])有两个目的.创建用户如果他/她的唯一facebook uid不在数据库ELSE中,如果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

在这里,我们尝试找到一个匹配给定提供者的用户和来自哈希的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 %>

那么,现在我们可以向facebook发送请求了.一个问题仍然是我们无法实际处理回调.为此,我们需要做以下事情……

>添加获取’auth /:provider / callback’=> routes.rb文件的’sessions #create_facebook’
>使用Facebook提供的方便的Javascript SDK.让我们创建一个使用此SDK的自定义javascript文件…

应用程序/资产/ JavaScript的/ 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'%>

希望这有助于那些想从头开始构建身份验证系统的人:)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读