[RUBY] [Rails 6] Registrieren und Anmelden mit Devise + SNS-Authentifizierung (mehrere Links zulässig)

Einführung

Erstellen Sie eine Authentifizierung, die mit mehreren SNS verknüpft werden kann. Die Entwicklung wird wie implementiert fortgesetzt. Wir werden nicht auf den Erwerb jedes API-Schlüssels eingehen. Bitte überprüfen Sie dies entsprechend. Dieses Mal werden wir es auf Facebook und Twitter implementieren, aber ich denke, dass es im Grunde das gleiche für andere SNS ist.

Umgebung

Umgebung


Windows10
ruby 2.6.6
Rails 6.0.3.1

Vorbereitung

Edelstein hinzugefügt

Gemfile


gem 'omniauth'
gem 'omniauth-facebook'
gem 'omniauth-twitter'

Bitte bündeln Sie die Installation nach dem Speichern.

Schreiben Sie den API-Schlüssel in credentials.yml

Informationen zu Windows finden Sie im Vorherigen Artikel.

credentials.yml



facebook:
  api_key: pk_test_~
  secret_key: sk_test_~
twitter:
  api_key: pk_test_~
  secret_key: sk_test_~
Einstellungen vornehmen

In config / initializer.

devise.rb


#Fügen Sie Folgendes hinzu
config.omniauth :facebook, Rails.application.credentials.facebook[:api_key], Rails.application.credentials.facebook[:secret_key], scope: 'email', info_fields: 'email,name'
config.omniauth :twitter, Rails.application.credentials.twitter[:api_key], Rails.application.credentials.twitter[:secret_key], scope: 'email', callback_url: 'https://localhost:3000/users/auth/twitter/callback'

Es scheint, dass Twitter die Rückruf-URL angeben muss.

Erstellen Sie ein soziales Modell

Dieses Mal wird davon ausgegangen, dass das Benutzermodell bereits in Devise erstellt wurde. Sie können dem Benutzermodell Spalten hinzufügen. Dieses Mal erstellen wir jedoch ein neues soziales Modell, das mit dem Benutzermodell verknüpft ist. (Das Benutzermodell und das Sozialmodell haben eine Eins-zu-Viele-Beziehung.)

console


rails g model social

Das Sozialmodell sollte user_id, provider (mit "facebook", "twitter" usw.) und uid (mit der ID, die jedem SNS-Konto zugeordnet werden soll) enthalten.

2020~create_socials.rb


class CreateSocials < ActiveRecord::Migration[6.0]
  def change
    create_table :socials do |t|
      t.references :user, null: false, foreign_key: true
      t.string :provider, null: false
      t.string :uid, null: false
      t.timestamps
    end
  end
end

Nach dem Speichern werden die Schienen db: migriert.

Verband

user.rb


has_many :socials, dependent: :destroy#hinzufügen
devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable, 
          :omniauthable#hinzufügen

social.rb


belongs_to :user
validates :uid, uniqueness: {scope: :provider}#Verhindern Sie mehrere Registrierungen innerhalb desselben Anbieters

Verhindern Sie, dass dasselbe SNS-Konto mit mehreren Benutzern verknüpft wird. Ich denke, es ist in Ordnung, wenn Sie nicht "{scope :: provider}" haben, aber nur für den Fall.

Implementierung

Erstellen Sie einen Rückrufprozess

routes.rb


devise_for :users, controllers: {
  sessions: 'users/sessions',
  password: 'users/password',
  registrations: 'users/registrations',
  omniauth_callbacks: 'users/omniauth_callbacks'#hinzufügen
  }

Unten in app / controller / users / omniauth_callbacks_controller.rb. (Überprüfen Sie anhand von Schienenrouten usw., und legen Sie die Methode hier für jedes Umleitungsziel fest.)

omniauth_callbacks_controller.rb


class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController

 def facebook
    if request.env['omniauth.auth'].info.email.blank?#Erlauben Sie E-Mails auf Facebook?
      redirect_to '/users/auth/facebook?auth_type=rerequest&scope=email'
    end
    callback_from :facebook
  end

  def twitter
    callback_from :twitter
  end


  private

  def callback_from(provider)
    provider = provider.to_s

    if user_signed_in?
      @user = current_user
      User.attach_social(request.env['omniauth.auth'], @user.id)#Später anhängen_sozial machen. Übergeben Sie die Informationen von SNS und die ID des angemeldeten Benutzers.
    else
      @user = User.find_omniauth(request.env['omniauth.auth'])#Später finden_Machen Sie Omniauth. Übergeben Sie Informationen von SNS.
    end

    if @user.persisted?#Registriert oder wenn Sie sich registrieren können
      flash[:notice] = I18n.t('devise.omniauth_callbacks.success', kind: provider.capitalize)
      sign_in_and_redirect @user, event: :authentication
    else
      session["devise.#{provider}_data"] = request.env['omniauth.auth']
      redirect_to new_user_registration_url
    end
  end
end

Übergeben Sie den SNS-Typ der Umleitungsquelle an "callback_from", um ihn zu isolieren. In "callback_from" wurde "Registrierung neuer Benutzer durch SNS-Authentifizierung oder Anmeldung des SNS-authentifizierten Benutzers" oder "SNS-Kooperation des angemeldeten Benutzers" getrennt. Die Verarbeitung von "nach Registrierung", "nach Anmeldung" und "nach Zusammenarbeit" wird diesmal nicht aufgeteilt, sondern alle werden auf die Benutzerseite umgeleitet.

Schreiben Sie als Nächstes jeden Prozess in User.rb.

user.rb


 def self.find_omniauth(auth)#Neue Registrierung oder Sns-Login mit SNS-Authentifizierung
    social = Social.where(uid: auth.uid, provider: auth.provider).first
    unless social.blank?#sns zertifiziert(Einloggen)
      user = User.find(social.user.id)
    else#Neue Registrierung mit sns-Authentifizierung
      temp_pass = Devise.friendly_token[0,20]#Dieses Mal werde ich vorerst ein zufälliges Passwort erstellen
      user = User.create!(
        username: auth.info.name,
        email: auth.info.email,
        password: temp_pass,
        password_confirmation: temp_pass,
      )
      social = Social.create!(
        user_id: user.id,
        provider: auth.provider,
        uid: auth.uid,
      )
    end

    return user
 end

 def self.attach_social(auth, user_id)#Beim Hinzufügen von Sns-Verknüpfung
    social = Social.create!(
      user_id: user_id,
      provider: auth.provider,
      uid: auth.uid,
    )
  end

Zum Zeitpunkt der "Registrierung neuer Benutzer durch SNS-Authentifizierung oder Anmeldung eines SNS-authentifizierten Benutzers" wird es weiter in "neue Registrierung" und "Anmeldung" unterteilt. Zum Zeitpunkt der "neuen Registrierung" werden sowohl Benutzer als auch Soziales erstellt (gleichzeitig werden Benutzer und Soziales verknüpft) und der Benutzer wird zurückgegeben. Zum Zeitpunkt der "Anmeldung" wird Social nach den von SNS gesendeten Informationen (auth.uid und auth.provider) durchsucht und der zugehörige Benutzer zurückgegeben. Zum Zeitpunkt der "SNS-Verknüpfung des angemeldeten Benutzers" wird nur "Social" erstellt. Es erhält user_id, um es dem angemeldeten Benutzer zuzuordnen.

Dies ist das Ende des Prozesses. Wenn Sie danach einen Link mit "user_facebook_omniauth_authorize_path" usw. erstellen, werden je nach Situation des Benutzers eine neue Registrierung, Anmeldung und Zusammenarbeit durchgeführt.

Das Ende

Eigentlich denke ich, es wäre besser, einen Link zum verknüpften SNS zu erstellen, einen Mechanismus zum Zurücksetzen des Kennworts bei der Neuregistrierung im SNS, die E-Mail-Authentifizierung von Devise, eine Schaltfläche zum Abbrechen des Links usw., aber vorerst die Mindestkonfiguration habe es gerade geschafft. Ich studiere Rails, daher denke ich, dass es viele Orte gibt, die nicht schlau sind. Wenn Sie etwas Seltsames tun, lassen Sie es mich bitte wissen!

Recommended Posts

[Rails 6] Registrieren und Anmelden mit Devise + SNS-Authentifizierung (mehrere Links zulässig)
[Ruby on Rails] So melden Sie sich nur mit Ihrem Namen und Passwort mit dem Gem-Gerät an
Erstellen Sie die Authentifizierungsfunktion in der Rails-Anwendung mit devise
Erstellen Sie eine Bulletin-Board-API mit Autorisierung in Rails 6 # 12 Assoziation von Benutzer und Beitrag
Protokollaggregation und -analyse (Arbeiten mit AWS Athena in Java)
[Rails] Suche aus mehreren Spalten + Bedingungen mit Gem und Ransack
[Rails] Probleme, die mit devise nicht registriert / angemeldet werden können
Implementieren Sie die Anmeldefunktion in Rails einfach mit Name und Passwort (3).
Implementieren Sie die Benutzerregistrierungsfunktion und die Unternehmensregistrierungsfunktion separat in Rails devise
[Rails] Erhalten Sie access_token zum Zeitpunkt der Twitter-Authentifizierung mit Sorcery und speichern Sie es in der Datenbank
Erstellen Sie eine Bulletin-Board-API mit Autorisierung in Rails 6 # 11. Benutzermodelltest und Validierung hinzugefügt
Japanisieren Sie mit i18n mit Rails
Implementieren Sie die LTI-Authentifizierung in Rails
Verwenden Sie mit Rails 6.0 mehrere Datenbanken
Verwenden Sie mehrere Kontrollkästchen in Rails6!