• Inspiración
  • Tutoriales
  • Bootcamp

En1Mes

  • Inspiración
  • Tutoriales
  • Bootcamp

Login con facebook en rails 4.1 y 4.2

Login con Facebook

En este tutorial voy a explicar como crear un sistema de log in con Facebook ocupando devise.

El concepto es el siguiente, el botón de login de Facebook no pertenece a tu sistema, si no que pertenece al sistema Facebook. Cuando este valida exitosamente al usuario que ingresa un sitio lo redirige a una página que le fue designada, esta redirección recibe el nombre de callback.

Gracias a la gema omniauth y omniauth-facebook podemos manejar de forma sencilla el callback y la autenticación a través de un hash el cual procesaremos y guardaremos en el modelo. Ya teniendo la información en el modelo, basta con un query para determinar si el usuario está registrado o no.

Para hacerlo más interesante, vamos a hacer que el sistema permita ambos accesos simultáneamente, o sea por Email o por Facebook.

Paso 1: Hacer una cuenta de Facebook Developer

Para construir una app con Facebook lo primero que debemos hacer es crearnos una cuenta en developers.facebook.com

Luego debemos ir My APPs, seleccionar la opción www, decir que nuestra app no es la versión de prueba de otra app y marcar una categoría. Luego Facebook nos ofrecerá la opción de seguir un quick start, pero por ahora la saltaremos.

Una vez creada la aplicación vamos a la sección settings, añadimos una plataforma del tipo website y en el dice Site URL ponemos localhost:3000 (después necesitaremos definir otra app en FB para la versión de producción).

Paso 2: Instalando la gema dotenv.

Ahora dentro de nuestra aplicación Rails vamos a instalar la gema .dotenv dentro del grupo de desarrollo y test, esta la ocuparemos para poner nuestras accesos de Facebook sin exponerlos a todo el mundo cuando publiquemos o compartamos nuestro proyecto.

group :development, :test do
 gem 'dotenv-rails'
end

El uso de la gema es bastante sencillo, se encuentra detallado en: https://github.com/bkeepers/dotenv pero principalmente consiste en crear en la raíz del proyecto un archivo llamado .env y dentro poner nuestras claves de la siguiente forma:

FB_APP_ID=AppIdEntregadaPorFacebook
FB_SECRET_KEY=ClaveEntregadaPorFacebook

Las claves no se agregan como string, o sea NO hay que poner las comillas de los strings, ej:

FB_APP_ID=AFCE00424CDEFA

luego el archivo .env lo agregamos al gitignore, de esta forma nos aseguramos de no commitearlo por casualidad.

Para hacer eso abrimos el archivo .gitignore y ponememos dentro del archivo.

/.env

Tip: Para que las personas con las que colaboras en el proyecto sepan que son necesarias estas claves, es bueno especificarlo en un archivo readme del proyecto.

Paso 3: Agregar la gema devise y omniauth.

En este caso yo ocuparé el modelo User, pero es perfectamente posible ocupar otro. Si no sabes como instalar Devise puedes ocupar el tutorial oficial.

gem 'devise'
gem 'omniauth'
gem 'omniauth-facebook'

y luego en el terminal dentro de la carpeta del proyecto:

bundle install

Paso 3.1: Instalar la gema devise

rails generate devise:install

Paso 3.2: Crear un modelo de usuario con devise

rails generate devise User

Paso 3.3: Generar vistas custom para poder modificarlas y agregar el botón de login

rails generate devise:views

Paso 3.4 generar el scope de los controllers para poder modificar la lógica de devise y agregar los callbacks

rails generate devise:controllers users

Para que Rails entienda que debe ocupar los nuevos controllers generados entonces hay que especificar en el archivo routes.rb, para eso hay que remplazar la línea puesta previamente que dice devise_for :users

devise_for :users, controllers: { 
  registrations: "users/registrations",
  sessions: "users/sessions",
  passwords: "users/passwords"}

En este paso vamos a hacer una cosa más, que es agregar la ruta para manejar el callback producido por facebook cuando te loggeas.

devise_for :users, controllers: {
  registrations: "users/registrations",
  sessions: "users/sessions",
  passwords: "users/passwords",
  omniauth_callbacks: "users/omniauth_callbacks"}

ADVERTENCIA: si copiaste la línea devise_for :users, controllers:{ regis …} sin remplazar la anterior tendrás un error.

Paso 4: Hacemos nuestro modelo User compatible con omniauth.

Para lograr este objetivo debemos agregar la siguiente línea al modelo de usuarios (dentro del archivo models/user.rb) , puede ser justo debajo de la línea anterior de devise

devise :omniauthable, omniauth_providers: [:facebook]

Paso 5:

Tenemos que adaptar el modelo para que sea capaz de almacenar los datos necesarios de Facebook, para eso crearemos una migración, esta migración contendrá al provider (en este caso será Facebook), el user id de Facebook y el nombre con el que el usuario está registrado en Facebook.

Para generar la migración, escribiremos en el bash:

rails g migration AddOmniauthColumnsToUser

y dentro de la migración agregaremos dentro:

def change    
  add_column :users, :provider, :string    
  add_column :users, :uid, :string    
  add_column :users, :name, :string  
end

para correr las migraciones hacemos:

rake db:migrate

Paso 6: Método para buscar los usuarios

Dentro del mismo modelo, o sea dentro del archivo app/models/user.rb necesitamos un método para revisar si el usuario ya ha entrado previamente con Facebook y que nos devuelva el usuario, si no, revisamos si el usuario se registró previamente por email y en el último caso revisamos que no haya estado previamente registrado lo creamos.

def self.find_for_facebook_oauth(auth, signed_in_resource=nil)      
  user = User.where(provider: auth.provider, uid: auth.uid).first       
  # The User was found in our database    
  return user if user    
  # Check if the User is already registered without Facebook      
  user = User.where(email: auth.info.email).first 
  return user if user
  User.create(
    name: auth.extra.raw_info.name,
    provider: auth.provider, uid: auth.uid,
    email: auth.info.email,
    password: Devise.friendly_token[0,20])  
end

Paso 7: Configurar Omniauth

Avamos a agregar dentro del archivo iniatializers/devise.rb el Facebook Api Key y el Facebook Secret Id que agregamos en el paso 1 al archivo .env, para poder referirnos a las variables de entorno lo hacemos a través de env.

config.omniauth :facebook, ENV['FB_APP_ID'], ENV['FB_SECRET_KEY']

Como cualquier archivo dentro de iniatilizers, después de modificarlo hay que reiniciar el servidor.

Paso 8: Crear un método en el controller para buscar al usuario o redirigir

En el controller app/controllers/users/omniauth_callbacks_controller.rb debemos manejar la lógica de la búsqueda y redirección.

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  include ApplicationHelper
  def facebook
    # Attempt to find the User
    @user = User.find_for_facebook_oauth(
      request.env["omniauth.auth"], 
      current_user
    )
    
    if @user.persisted?
      sign_in_and_redirect @user, 
        :event => :authentication 
      set_flash_message(:notice, 
        :success, 
        :kind => "Facebook") if is_navigational_format?
    else
      redirect_to new_user_registration_url
    end
  end
  def passthru
    render :file => "#{Rails.root}/public/404.html", :status => 404, :layout => false
  end
end

Paso 9: Incorporar el SDK de Facebook

La mejor forma de hacerlo es a través de una vista parcial, para eso vamos a crear dentro de la carpeta app/views la carpeta shared y dentro vamos a crear el archivo _facebook_sdk.html.erb

dentro del archivo:

<div id="fb-root"></div>
<script>(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#xfbml=1&appId=<%=ENV['FB_APP_ID']%>&version=v2.0";
  fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));</script>

Tomar en cuenta que para que este script funcione se debe haber hecho el paso 2, o sea instalar la gema dotenv-rails y poner dentro del archivo .env el número de la appID de facebook.

dentro del archivo app/views/layouts/application.rb debemos incorporar la vista que acabamos de crear, para eso ponemos dentro de body, arriba de yield:

<%= render 'shared/facebook_sdk' %>

Paso 10: probar

Lo último que falta es probar, para eso vamos a ir a la página localhost:3000/users/sign_in

#HappyCoding

Feb 3, 2015Gonzalo Sánchez
Share Button
  • El Autor
  • Últimos Posts

About Gonzalo Sánchez

Emprendedor lean, Ingeniero civil informático dedicado al desarrollo de una mejor web con ruby on rails. Fanático de los números y las métricas y por sobre todo fundador de en1mes.
  • Mostbet guncel giris: en guncel bahis secenekleri - May 8, 2025
  • Mostbet Casino: Your Oasis of Gaming Pleasure, Always - May 6, 2025
  • Bahis ve emsallar Most Bet ile - May 6, 2025
  • Mostbet Resmi Sitesi: Bahis Severlerin Tercihi - May 3, 2025
  • MostBet Rehberi: Bahis Dunyasinda Basariya Ulasmanin Yollari - May 2, 2025
  • Basarili Bir Bahis Deneyimi Icin Ipuclari Most bet Platformunda - April 30, 2025
  • Mostbet Giris 2025: Bahis Stratejileri ve Taktikler - April 28, 2025
  • Bahis Dunyasinda Guvende Kalmanin Yollari Mostbet ile - April 25, 2025
  • Mostbet yeni giris adresi olarak sadece internet sitesi - April 23, 2025
  • Bahis Dunyasinda MostBet ile Guvenli Adimlar Atin - April 22, 2025
10 years ago 4 Comments RubyRuby on Rails16,032
EL ASSET PATH DE RAILSFriendly URL en Rails
You Might Also Like
 
¿Cómo Escoger Un Lenguaje De Programación Para Tu Emprendimiento?
 
Bring your Cup | 4º Lugar mundial en el hack4good
Comments: 4
  1. David
    10 years ago

    Puedes usar la gema Figaro también. Con la cual te genera un application.yml que se anexa solo al gitignore.

    ReplyCancel
  2. David
    10 years ago

    El paso 5 se puede resumir un poco mas:

    rails g migration AddOmniauthColumnsToUsuario provider_facebook:string uid_facebook:string name_facebook:string

    Con eso se generan las columnas a crear.

    ReplyCancel
  3. Oscar
    10 years ago

    Hola, al probar localhost:3000/users/sign_in (Paso: 10) me arrojo este error:
    undefined method `omniauth_authorize_path' for #<#:0x007f9f252ff258>

    Extracted source (around line #23):
    21
    22
    23
    24
    25

    Cómo poder solucionarlo.
    Saludos!

    ReplyCancel
  4. Gustavo
    9 years ago

    Hola, cuando doy click sobre "Ingresar con Facebook" me aparece el siguiente error:
    Faraday::SSLError
    SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed

    ReplyCancel

Leave a Reply to David Cancel reply

Tags
mostbetslotticamostbet UZslottica PLRuby on Railsaviatoraviator KZozwincasinoozwincasino AUemprendimientos digitalesfortunetiger BRfortunetigerTutorialesDiseñoLondonLondon UZbj88slottica BRHerramientashtml5WordpressrubyLanding Pageparty poker casinogratogana juegos en vivoแทงบอลออนไลน์Bases de datoswash serviceหวยออนไลน์gratogana entrar20bet plkudos casino no deposit bonus 2024kudos casino loginTallereshackathonkudos casino no deposit bonuspartycasino entrarHeroku1win AZ1winTipsPáginas WebNitrousInspiracióncbd
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • Interesado en otros tipos de emprendimiento?

    Quieres aprender a importar y exportar productos a todo el mundo? entra aquí

  • LOMBOKTOTO
  • LOMBOKTOTO
  • LOMBOKTOTO
  • LOMBOKTOTO
  • LOMBOKTOTO
  • LOMBOKTOTO
  • LOMBOKTOTO
  • LOMBOKTOTO
  • LOMBOKTOTO
  • LOMBOKTOTO
  • LOMBOKTOTO
  • LOMBOKTOTO
  • LOMBOKTOTO
  • LOMBOKTOTO
  • No te pierdas ningún artículo.

  • RAMALANTOTO
  • RAMALANTOTO
  • RAMALANTOTO
  • RAMALANTOTO
  • RAMALANTOTO
  • RAMALANTOTO
  • RAMALANTOTO
  • RAMALANTOTO
  • RAMALANTOTO
  • RAMALANTOTO
  • RAMALANTOTO
  • RAMALANTOTO
  • RAMALANTOTO
  • RAMALANTOTO
  • 2016 © En 1 Mes