Vídeo: Permita que usuários façam login no seu app Rails usando o Facebook
Nesse novo screencast, vou ensinar como adicionar uma interessante funcionalidade ao seu app: autenticação usando o Facebook.
Para ficar mais interessante, usei um projeto real: o Easy Bills. O projeto usa Ruby e Ruby on Rails e adicionalmente, eu incluí a gem omniauth-facebook.
Abaixo, você encontra os arquivos que eu criei ou alterei no vídeo:
Gemfile
:
rubygem 'omniauth-facebook'
app/assets/images/social-sign-in/facebook.svg
:
xml<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="35px" height="35px" viewBox="0 0 300 300" enable-background="new 0 0 266.893 266.895" xml:space="preserve"> <path id="f" fill="#FFFFFF" d="M182.409,262.307v-99.803h33.499l5.016-38.895h-38.515V98.777c0-11.261,3.127-18.935,19.275-18.935 l20.596-0.009V45.045c-3.562-0.474-15.788-1.533-30.012-1.533c-29.695,0-50.025,18.126-50.025,51.413v28.684h-33.585v38.895h33.585 v99.803H182.409z"/> </svg>
app/assets/stylesheets/authentication.sass
(ou app/assets/stylesheets/application.sass
):
sass@import 'modules/social-buttons'
app/assets/stylesheets/modules/social-buttons.sass
:
sass// https://github.com/vagnervjs/social-signin-btns $services: google #DD4B39, facebook #3B5998, twitter #00ACED, microsoft #e3b30d, github #2a2a2a, foursquare #95c330, instagram #906248, linkedin #0b5ea3, evernote #5ca629, dropbox #1b73d1 .btn-si background-position: 1em background-repeat: no-repeat background-size: 2em border-radius: .5em border: none color: #fff cursor: pointer font-size: 1em line-height: 1em padding: 0 2em 0 4em text-decoration: none transition: all .5s @each $service in $services .btn-#{nth($service, 1)} background-color: #{nth($service, 2)} &, &:hover, &:active background-image: image-url("social-sign-in/#{nth($service, 1)}.svg") color: #fff &:hover background-color: lighten(nth($service, 2), 10%) &:active background-color: darken(nth($service, 2), 10%) .btn-si-a padding: 15px 15px 15px 65px !important font-family: arial .smaller .btn-si-a padding-left: 40px !important font-size: 12px
app/controllers/users/omniauth_callbacks_controller.rb
:
rubymodule Users class OmniauthCallbacksController < Devise::OmniauthCallbacksController def facebook @user = User.from_omniauth(request.env['omniauth.auth']) if @user.persisted? sign_in_and_redirect @user, event: :authentication # Throws if @user is not activated set_flash_message(:notice, :success, kind: 'Facebook') if is_navigational_format? else session['devise.facebook_data'] = request.env['omniauth.auth'] redirect_to new_user_registration_url end end def failure redirect_to new_user_session_path end end end
app/models/concerns/omniauthenticable.rb
:
rubymodule Omniauthenticable extend ActiveSupport::Concern included do def self.from_omniauth(auth) existing_user = User.find_by(email: auth['info']['email']) if existing_user existing_user.update!(provider: auth.provider, uid: auth.uid) existing_user else where(provider: auth.provider, uid: auth.uid).first_or_create do |user| user.email = auth.info.email user.password = Devise.friendly_token[0, 20] user.password_confirmation = user.password user.name = auth.info.name user.photo = auth.info.image user.skip_confirmation! end end end def self.new_with_session(params, session) super.tap do |user| data = session['devise.facebook_data'] && session['devise.facebook_data']['extra']['raw_info'] user.email = data['email'] if data && user.email.blank? end end end end
app/models/user.rb
:
rubyclass User < ApplicationRecord include Omniauthenticable devise :omniauthable, omniauth_providers: %i[facebook] # etc end
app/views/devise/sessions/new.html.haml
:
haml%hr.m-t-25 .m-b-10 or .fg-line.m-b-10 = link_to 'Sign in with Facebook', user_facebook_omniauth_authorize_path, class: 'btn btn-si btn-si-a btn-facebook'
config/initializers/devise.rb
:
rubyconfig.omniauth :facebook, 'FACEBOOK_APP_ID', 'FACEBOOK_APP_SECRET'
config/routes.rb
:
rubydevise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks', # etc }
db/migrate/20171204023306_add_omniauth_to_users.rb
:
rubyclass AddOmniauthToUsers < ActiveRecord::Migration[5.1] def change add_column :users, :provider, :string add_column :users, :uid, :string end end