Inicio de sesi贸n de Linkedin OAuth2 para Rails

Hay una gran joya para autenticarse con Linked named: omniauth-linkedin-oauth2

Hubo un problema con la gema original, as铆 que la bifurqu茅 y la ajust茅, as铆 que si茅ntete libre de bifurcarla o usar la m铆a.

Crear una aplicaci贸n de Linkedin

Lo primero es ir a https://www.linkedin.com/developer/apps y crear una aplicaci贸n para autenticarse.

Nota importante sobre la configuraci贸n de la URL:

Debe configurar las URL de devoluci贸n de llamada para cada entorno en la aplicaci贸n de Linkedin para que las devoluciones de llamada funcionen correctamente.

Para desarrollo:

http://appname.dev/auth/linkedin/callback

Para producci贸n:

https://appname.com/auth/linkedin/callback

1. Comience agregando la gema

gem 'omniauth-linkedin-oauth2', git: 'https://github.com/Devato/omniauth-linkedin-oauth2.git'

2. Luego configure el inicializador:

#config/initializers/omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
provider
:linkedin, ENV['LINKEDIN_CLIENT_ID'], ENV['LINKEDIN_CLIENT_SECRET'], secure_image_url: true
end

Ahora volvamos a la URL de devoluci贸n de llamada. Esta es la URL a la que se redirigir谩 a un usuario dentro de la aplicaci贸n despu茅s de una autenticaci贸n exitosa y una autorizaci贸n aprobada (la solicitud tambi茅n contendr谩 los datos y el token del usuario). Todas las estrategias de OmniAuth esperan que la URL de devoluci贸n de llamada sea igual a “/ auth /: proveedor / devoluci贸n de llamada”. : el proveedor toma el nombre de la estrategia (鈥渢witter鈥, 鈥渇acebook鈥, 鈥渓inkedin鈥, etc.) como se indica en el inicializador.

3. Agrega las rutas

#config/routes.rb
get '/auth/:provider/callback', to: 'oauth#callback', as: 'oauth_callback'
get '/auth/failure', to: 'oauth#failure', as: 'oauth_failure'

4. Un enlace para enviar la solicitud a Linkedin (esto obviamente no funcionar谩 todav铆a).

= link_to 'Register with Linkedin', '/auth/linkedin' 

5. Prep谩rese para almacenar los datos

Puede configurar almacenar los datos de la forma que desee. Cre茅 un modelo separado para contener todo. Aqu铆 est谩 la migraci贸n:

class CreateOauthAccounts < ActiveRecord::Migration
def change
create_table
:oauth_accounts do |t|
t
.belongs_to :user, index: true, foreign_key: true
t
.string :provider
t
.string :uid
t
.string :image_url
t
.string :profile_url
t
.string :access_token
t
.text :raw_data
t
.timestamps null: false
end
end
end

6. Procese la devoluci贸n de llamada.

Genere un Oauthcontrolador para mantener las cosas separadas:

#app/controllers/oauth_controller.rb
class OauthController < ApplicationController

def callback
begin
oauth
= OauthService.new(request.env['omniauth.auth'])
if oauth_account = oauth.create_oauth_account!
...
redirect_to
Config.provider_login_path
end
rescue => e
flash
[:alert] = "There was an error while trying to authenticate your account."
redirect_to register_path

end
end

def failure
flash
[:alert] = "There was an error while trying to authenticate your account."
redirect_to register_path

end

end

Notar谩s que hay dos m茅todos para manejar la respuesta de linkedin. callbacky failure. La devoluci贸n de llamada est谩 procesando los datos y creando los registros seg煤n sea necesario. es un servicio personalizado que se utiliza para procesar los datos.request.env['omniauth.auth']OauthService

7. El servicio que procesa los datos de devoluci贸n de llamada

Pas茅 este procesamiento a una clase de servicio para mantener todo organizado:

#app/services/oauth_service.rb
class OauthService
attr_reader
:auth_hash

def initialize(auth_hash)
@auth_hash = auth_hash
end

def create_oauth_account!
unless oauth_account = OauthAccount.where(uid: @auth_hash[:uid]).first
oauth_account
= OauthAccount.create!(oauth_account_params)
end
oauth_account

end

private

def oauth_account_params
{ uid: @auth_hash[:uid],
provider
: @auth_hash[:provider],
image_url
: @auth_hash[:info][:image],
profile_url
: @auth_hash[:info][:urls][:public_profile],
raw_data
: @auth_hash[:extra][:raw_info].to_json }
end

end

Hay muchas formas diferentes de lograr esto, pero esto se sinti贸 bien y fue bastante sencillo de probar.

A脩ADIR COBERTURA DE PRUEBA RSPEC

Hay algunos matices de probar este proceso, y esto es lo que funcion贸 para configurar la simulaci贸n:

1. Configurar macro para burlarse de la respuesta

#spec/support/omniauth_macros.rb
module OmniauthMacros
def mock_auth_hash
# The mock_auth configuration allows you to set per-provider (or default)
# authentication hashes to return during integration testing.
OmniAuth.config.mock_auth[:linkedin] = OmniAuth::AuthHash.new({
'provider' => 'linkedin',
'uid' => '123545',
'info' => {
'name' => 'mockuser',
'image' => 'mock_user_thumbnail_url',
'first_name' => 'john',
'last_name' => 'doe',
'email' => '[email protected]',
'urls' => {
'public_profile' => 'http://test.test/public_profile'
}
},
'credentials' => {
'token' => 'mock_token',
'secret' => 'mock_secret'
},
'extra' => {
'raw_info' => '{"json":"data"}'
}
})
end
end

2. Incluya esta macro en su configuraci贸n de RSpec:

#spec/rails_helper.rb
RSpec.configure do |config|
config
.include(OmniauthMacros)
end

Luego, debajo del bloque de configuraci贸n, configure OmniAuth en modo de prueba:

OmniAuth.config.test_mode = true

3. Agregar especificaci贸n de solicitud:

#spec/requests/registration_spec.rb

require "rails_helper"

describe
"home#register as a provider", :type => :request do

it
"redirects to oauth#callback" do
get '/auth/linkedin'
expect
(response).to redirect_to(oauth_callback_path(:linkedin))
end

end

Debido a que OmniAuthest谩 en modo de prueba, deber铆a redirigir a la devoluci贸n de llamada.

4. Especificaciones de OauthController:

#spec/controllers/oauth_controller_spec.rb

require 'rails_helper'

describe
OauthController, type: :controller do

before
(:each) do
mock_auth_hash

request
.env['omniauth.auth'] = OmniAuth.config.mock_auth[:linkedin]
end

after
(:each) do
OmniAuth.config.mock_auth[:linkedin] = nil
end

describe
'GET #callback' do
it
'expects omniauth.auth to be be_truthy' do
get :callback, provider: :linkedin
expect
(request.env['omniauth.auth']).to be_truthy
end

it
'completes the registration process successfully' do
get :callback, provider: :linkedin
expect
(page).to redirect_to Config.provider_login_path
end

it
'creates an oauth_account record' do
expect
{
get :callback, provider: :linkedin
}.to change { OauthAccount.count }.by(1)
end

end

end

Notar谩 que llamar mock_auth_hashy configurar prepara los datos simulados para probarlos.request.env['omniauth.auth']

Estas pruebas b谩sicas garantizan que el simulacro funcione correctamente, que se nos redirija a la ruta adecuada y que el OauthAccountregistro se haya creado correctamente.

Hay muchas formas diferentes de lograr estos mismos resultados, pero esto es lo que funcion贸 bien para nosotros y, con suerte, es una buena referencia para cualquiera que necesite lograr las mismas cosas.