Ruby on rails 如何集成facebook登录以进行登录和注册

Ruby on rails 如何集成facebook登录以进行登录和注册,ruby-on-rails,session,facebook-javascript-sdk,facebook-login,Ruby On Rails,Session,Facebook Javascript Sdk,Facebook Login,我已经有了一个用户模型和控制器以及一个会话控制器。用户可以在没有facebook的情况下从我的应用程序注册和登录。然而,我还想集成facebook登录,使其与登录和注册、用户模型、控制器和已经编程的会话一起工作。我可以集成大部分Facebook API,但唯一一件我从未做过、也不知道如何做的事情就是让Facebook与应用程序并肩工作。这是我第一次集成facebook,我不熟悉他们的API。只是学习。非常感谢你的帮助。以下是我的逻辑或伪代码: On Facebook Login { Get th

我已经有了一个用户模型和控制器以及一个会话控制器。用户可以在没有facebook的情况下从我的应用程序注册和登录。然而,我还想集成facebook登录,使其与登录和注册、用户模型、控制器和已经编程的会话一起工作。我可以集成大部分Facebook API,但唯一一件我从未做过、也不知道如何做的事情就是让Facebook与应用程序并肩工作。这是我第一次集成facebook,我不熟悉他们的API。只是学习。非常感谢你的帮助。以下是我的逻辑或伪代码:

On Facebook Login {
Get the Facebook user_id first_name email
if user email already exists set the current user = corresponding user in the database
if user_email does not exist in my database 
sign up the user{
user_name = facebook.user_name
user.email= facebook.user_email
user.Password = facebook_user_id + facebook.user_name
}
}
我的应用程序已经有了一些facebook API,登录facebook按钮可以工作,但它与我的应用程序的登录、会话和数据库不同步

这是我的用户\u控制器:

class UsersController < ApplicationController
before_action :logged_in_user, only: [:index, :edit, :update, :destroy,
                                    :following, :followers]
before_action :correct_user,   only: [:edit, :update]
before_action :admin_user,     only: :destroy
def index
@users = User.all.paginate(page: params[:page])
end
def show
@user = User.find(params[:id])
@posts = @user.posts.paginate(page: params[:page])
end
def new
@user = User.new
end
def create
@user = User.new(user_params)
if @user.save
log_in @user
  flash[:success] = "Welcome to Unstarv!"
  redirect_to @user
else
  render 'new'
end
end
def edit
@user = User.find(params[:id])
end
def update
@user = User.find(params[:id])
if @user.update_attributes(user_params)
  flash[:success] = "Profile updated"
  redirect_to @user
else
  render 'edit'
end
end
def destroy
    User.find(params[:id]).destroy
    flash[:success] = "User deleted"
    redirect_to users_url
end 
def following
@title = "Following"
@user  = User.find(params[:id])
@users = @user.following.paginate(page: params[:page])
render 'show_follow'
end
def followers
@title = "Followers"
@user  = User.find(params[:id])
@users = @user.followers.paginate(page: params[:page])
render 'show_follow'
end
private
def user_params
  params.require(:user).permit(:username, :email, :password,
                               :password_confirmation)
end
 # Confirms a logged-in user.
def logged_in_user
  unless logged_in?
    flash[:danger] = "Please log in."
    redirect_to login_url
  end
end
 # Confirms the correct user.
def correct_user
  @user = User.find(params[:id])
  redirect_to(root_url) unless @user == current_user
end
# Before filters
# Confirms a logged-in user.
def logged_in_user
  unless logged_in?
    store_location
    flash[:danger] = "Please log in."
    redirect_to login_url
  end
end
def correct_user
  @user = User.find(params[:id])
  redirect_to(root_url) unless current_user?(@user)
end
# Confirms an admin user.
def admin_user
  redirect_to(root_url) unless current_user.admin?
end
end
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by(email: params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
log_in user
  params[:session][:remember_me] == '1' ? remember(user) : forget(user)
  redirect_back_or user 
else
 flash.now[:danger] = 'Invalid email/password combination'
 render 'new'
end
end
def destroy
log_out if logged_in?
redirect_to root_url
end
end
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
include SessionsHelper
# Confirms a logged-in user.
def logged_in_user
  unless logged_in?
    store_location
    flash[:danger] = "Please log in."
    redirect_to login_url
  end
end
end
我的应用程序控制器:

class UsersController < ApplicationController
before_action :logged_in_user, only: [:index, :edit, :update, :destroy,
                                    :following, :followers]
before_action :correct_user,   only: [:edit, :update]
before_action :admin_user,     only: :destroy
def index
@users = User.all.paginate(page: params[:page])
end
def show
@user = User.find(params[:id])
@posts = @user.posts.paginate(page: params[:page])
end
def new
@user = User.new
end
def create
@user = User.new(user_params)
if @user.save
log_in @user
  flash[:success] = "Welcome to Unstarv!"
  redirect_to @user
else
  render 'new'
end
end
def edit
@user = User.find(params[:id])
end
def update
@user = User.find(params[:id])
if @user.update_attributes(user_params)
  flash[:success] = "Profile updated"
  redirect_to @user
else
  render 'edit'
end
end
def destroy
    User.find(params[:id]).destroy
    flash[:success] = "User deleted"
    redirect_to users_url
end 
def following
@title = "Following"
@user  = User.find(params[:id])
@users = @user.following.paginate(page: params[:page])
render 'show_follow'
end
def followers
@title = "Followers"
@user  = User.find(params[:id])
@users = @user.followers.paginate(page: params[:page])
render 'show_follow'
end
private
def user_params
  params.require(:user).permit(:username, :email, :password,
                               :password_confirmation)
end
 # Confirms a logged-in user.
def logged_in_user
  unless logged_in?
    flash[:danger] = "Please log in."
    redirect_to login_url
  end
end
 # Confirms the correct user.
def correct_user
  @user = User.find(params[:id])
  redirect_to(root_url) unless @user == current_user
end
# Before filters
# Confirms a logged-in user.
def logged_in_user
  unless logged_in?
    store_location
    flash[:danger] = "Please log in."
    redirect_to login_url
  end
end
def correct_user
  @user = User.find(params[:id])
  redirect_to(root_url) unless current_user?(@user)
end
# Confirms an admin user.
def admin_user
  redirect_to(root_url) unless current_user.admin?
end
end
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by(email: params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
log_in user
  params[:session][:remember_me] == '1' ? remember(user) : forget(user)
  redirect_back_or user 
else
 flash.now[:danger] = 'Invalid email/password combination'
 render 'new'
end
end
def destroy
log_out if logged_in?
redirect_to root_url
end
end
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
include SessionsHelper
# Confirms a logged-in user.
def logged_in_user
  unless logged_in?
    store_location
    flash[:danger] = "Please log in."
    redirect_to login_url
  end
end
end
class ApplicationController
下面是我的应用程序布局,其中集成了一些基本的facebook api:

<!DOCTYPE html>
<html>
<head>
<title> Unstarv</title>
<%= stylesheet_link_tag 'application', media: 'all',
                                       'data-turbolinks-track' => true %>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>
<%= render 'layouts/shim' %>
</head>
<body>
<div id="fb-root"></div>
<h1 id="fb-welcome"></h1>
<script>
// This is called with the results from from FB.getLoginStatus().
function statusChangeCallback(response) {
console.log('statusChangeCallback');
console.log(response);
// The response object is returned with a status field that lets the
// app know the current login status of the person.
// Full docs on the response object can be found in the documentation
// for FB.getLoginStatus().
if (response.status === 'connected') {
  // Logged into your app and Facebook.
  testAPI();
} else if (response.status === 'not_authorized') {
  // The person is logged into Facebook, but not your app.
  document.getElementById('status').innerHTML = 'Please log ' +
    'into this app.';
} else {
  // The person is not logged into Facebook, so we're not sure if
  // they are logged into this app or not.
  document.getElementById('status').innerHTML = 'Please log ' +
    'into Facebook.';
  }
  }

 // This function is called when someone finishes with the Login
 // Button.  See the onlogin handler attached to it in the sample
 // code below.
 function checkLoginState() {
 FB.getLoginStatus(function(response) {
  statusChangeCallback(response);
  });
 }

 window.fbAsyncInit = function() {
 FB.init({
 appId      : '1427074967594599',
 cookie     : true,  // enable cookies to allow the server to access 
                    // the session
 xfbml      : true,  // parse social plugins on this page
 version    : 'v2.3' // use version 2.3
 });

 // Now that we've initialized the JavaScript SDK, we call 
 // FB.getLoginStatus().  This function gets the state of the
 // person visiting this page and can return one of three states to
 // the callback you provide.  They can be:
 //
 // 1. Logged into your app ('connected')
 // 2. Logged into Facebook, but not your app ('not_authorized')
 // 3. Not logged into Facebook and can't tell if they are logged into
 //    your app or not.
 //
 // These three cases are handled in the callback function.

 FB.getLoginStatus(function(response) {
 statusChangeCallback(response);
 });

  };

 // Load the SDK asynchronously
  (function(d, s, id) {
  var js, fjs = d.getElementsByTagName(s)[0];
  if (d.getElementById(id)) return;
  js = d.createElement(s); js.id = id;
  js.src = "//connect.facebook.net/en_US/sdk.js";
  fjs.parentNode.insertBefore(js, fjs);
  }(document, 'script', 'facebook-jssdk'));

  // Here we run a very simple test of the Graph API after login is
  // successful.  See statusChangeCallback() for when this call is made.
  function testAPI() {
  console.log('Welcome!  Fetching your information.... ');
  FB.api('/me', function(response) {
  console.log('Successful login for: ' + response.name);
  document.getElementById('status').innerHTML =
    'Thanks for logging in, ' + response.name + '!';
   });
   }

  // Place following code after FB.init call.

  function onLogin(response) {
  if (response.status == 'connected') {
  FB.api('/me', function(data) {
  var welcomeBlock = document.getElementById('fb-welcome');
  welcomeBlock.innerHTML = 'Hello, ' + data.first_name + '!';
  });
  }
  }

  FB.getLoginStatus(function(response) {
  // Check login status on load, and if the user is
  // already logged in, go directly to the welcome message.
  if (response.status == 'connected') {
  onLogin(response);
  } else {
   // Otherwise, show Login dialog first.
FB.login(function(response) {
  onLogin(response);
}, {scope: 'user_friends, email, user_info'});
 }
});
</script>

<%= render 'layouts/header' %>



<div class="container">
<% flash.each do |message_type, message| %>
    <div class="alert alert-<%= message_type %>"><%= message %></div>
  <% end %>
  <%= yield %>
  <%= render 'layouts/footer' %>
</div>
</body>
</html>

Unstarv
正确%>
正确%>
//使用来自FB.getLoginStatus()的结果调用此函数。
函数statusChangeCallback(响应){
log('statusChangeCallback');
控制台日志(响应);
//响应对象返回的状态字段允许
//应用程序知道此人的当前登录状态。
//响应对象的完整文档可以在文档中找到
//对于FB.getLoginStatus()。
如果(response.status===“已连接”){
//登录你的应用程序和Facebook。
testAPI();
}else if(response.status===“未授权”){
//此人已登录Facebook,但未登录您的应用程序。
document.getElementById('status')。innerHTML='Please log'+
“进入此应用程序。”;
}否则{
//此人未登录Facebook,因此我们不确定是否
//他们是否登录到此应用程序。
document.getElementById('status')。innerHTML='Please log'+
“进入Facebook。”;
}
}
//当某人完成登录时调用此函数
//按钮。请参见示例中附加到它的onlogin处理程序
//代码如下。
函数checkLoginState(){
FB.getLoginStatus(函数(响应){
状态更改回调(响应);
});
}
window.fbAsyninit=函数(){
FB.init({
appId:'1427074967594599',
cookie:true,//启用cookie以允许服务器访问
//会议
xfbml:true,//解析此页面上的社交插件
版本:“v2.3”//使用版本2.3
});
//现在我们已经初始化了JavaScript SDK,我们调用
//getLoginStatus()。此函数用于获取
//访问此页面的人,可以将三种状态之一返回到
//您提供的回调。它们可以是:
//
//1.登录到您的应用程序(“已连接”)
//2.登录Facebook,但不登录你的应用程序(“未授权”)
//3.未登录Facebook,无法判断是否已登录
//你的应用与否。
//
//这三种情况在回调函数中处理。
FB.getLoginStatus(函数(响应){
状态更改回调(响应);
});
};
//异步加载SDK
(功能(d、s、id){
var js,fjs=d.getElementsByTagName[0];
if(d.getElementById(id))返回;
js=d.createElement;js.id=id;
js.src=“//connect.facebook.net/en_US/sdk.js”;
fjs.parentNode.insertBefore(js,fjs);
}(文档“脚本”、“facebook jssdk”);
//在这里,我们在登录完成后运行一个非常简单的Graph API测试
//成功。请参阅statusChangeCallback()了解何时进行此调用。
函数testAPI(){
log('欢迎!获取您的信息…);
FB.api('/me',函数(响应){
console.log('successfulllogin for:'+response.name);
document.getElementById('status').innerHTML=
'感谢您登录,'+response.name+'!';
});
}
//在FB.init调用之后放置以下代码。
函数onLogin(响应){
如果(response.status==“已连接”){
FB.api('/me',函数(数据){
var welcomeBlock=document.getElementById('fb-welcome');
welcomeBlock.innerHTML='Hello',+data.first_name+'!';
});
}
}
FB.getLoginStatus(函数(响应){
//检查加载时的登录状态,以及用户是否
//已登录,请直接转到欢迎消息。
如果(response.status==“已连接”){
onLogin(应答);
}否则{
//否则,首先显示登录对话框。
FB.登录(功能(响应){
onLogin(应答);
},{scope:'user\u friends,email,user\u info'});
}
});

如果回答您的问题

如何集成facebook登录以进行登录和注册

我建议你使用gem。它处理facebook的基础工作。你也可以使用gem,但不一定

那些宝石处理基本的工作人员。是的,你们也可以写你们自己的解决方案,把它包装到gem,但我认为这不是这个网站的问题

我建议用这种方式


FacebookAuth的理念是:

  • 您可以从Facebook获取用户数据,并可以预先填充用户表单数据(如姓名、照片等)
  • 若用户已经将facebook帐户连接到你们的应用程序,你们可以在每次facebook认证后将他登录到你们的应用程序,比如检查数据库中是否存在uid(你们从facebook获得的)
  • 在Facebook登录时
    获取Facebook用户id首名电子邮件

    对于电子邮件,您需要特殊的凭据,有时用户希望为您的应用程序使用其他电子邮件。或者他无法访问他在facebook上使用的电子邮件

    如果用户电子邮件已经存在,则设置当前用户=相应的用户 在数据库中

    如果用户_电子邮件在中不存在