2015-11-14 32 views
5

Próbowałem zadać to pytanie - i nie znalazłem żadnej pomocy.Devise Omniauth - konfigurowanie i definiowanie strategii

http://stackoverflow.com/questions/33493369/rails-devise-omniauth-problems-with-setup 

zrezygnowałem stara się rozwiązać problem i wykonany całkowicie nową aplikację z niczym innym w nim tak, że mogę spróbować zmniejszyć zakres innych błędów zakłócających.

W mojej nowej aplikacji dostaję teraz komunikat o błędzie, gdy kliknę link Nowa rejestracja/nowy użytkownik.

Podążałem za tutorialami castingów rails (po wypróbowaniu około 20 innych), aby uzyskać tę konfigurację. 1,5 roku i wciąż walczę.

Problem polega na sposobie zdefiniowania strategii w kontrolerze. Mam 4 strategie (twitter, Facebook, google i linkedin) i obecnie otrzymuję inny błąd dla każdego z nich, gdy próbuję kliknąć łącza, aby utworzyć nową rejestrację z tymi kontami:

Na Twitter: nieznane działanie akcja „twitter” nie można znaleźć dla użytkowników :: AuthenticationsController

na Facebooku:

Given URL is not permitted by the Application configuration: One or more of the given URLs is not permitted by the App's settings. It must match the Website URL or Canvas URL, or the domain must be a subdomain of one of the App's domains. 

Ten błąd jest, bo nie może dowiedzieć się, dokumentację Facebooka. Pokazuje, jak używać js do logowania z Facebookiem, gdzie próbuję użyć klejów w Railsach. Nie martwię się tym błędem. Myślę, że ma to coś wspólnego z tym, że moja strona nie jest zdefiniowana jako host lokalny, chociaż nie mogę znaleźć nigdzie innego niż adres URL wywołania zwrotnego w konsoli programisty Facebooka. Moje pytanie nie dotyczy tego problemu, znajdę pomoc, aby rozwiązać ten problem innym razem.

Dla LinkedIn:

Safari can’t open the page “https://www.linkedin.com/uas/oauth2/authorization?client_id=LINKEDIN_DEV_ID&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fusers%2Fauth%2Flinkedin%2Fcallback&response_type=code&scope=r_basicprofile+r_emailaddress&state=3fef961c10410464cd5b0ca49b25112ce53fb65f1a3c794f”. 

Błąd brzmi: „nie może dekodować dane surowe” (NSURLErrorDomain: -1015) Mam zwrotna OAuth2 zdefiniowany jako:

http://localhost:3000/users/auth/linkedin/callback 

nie mam wiesz, co tu jest złamane.

Dla Google:

translation missing: en.devise.authentications.user.failure 

Nowe rejestracje zobaczyć tylko odświeża po kliknięciu tego linku i komunikat o błędzie mówi powyżej. Nie wiem też, co powoduje ten błąd.

Każdy z błędów jest inny.

Mam folder w folderze kontrolerów o nazwie użytkownicy. Wewnątrz, że mam dwa kontrolery następująco:

uwierzytelnianie Kontroler:

class Users::AuthenticationsController < Devise::OmniauthCallbacksController 
    before_action :set_authentication, only: [:destroy] 

    def index 
    @authentications = current_user.authentications if current_user 
    end 


    def create 
    omniauth = request.env["omniauth.auth"] 
    authentication = Authentication.find_by_provider_and_uid(omniauth['provider'], omniauth['uid']) 
    if authentication 
     sign_in_and_redirect_user(:user, authentication.user.profile) 

    elsif current_user 
     current_user.authentications.create!(:provider => omniauth['provider'], :uid => omniauth['uid']) 
     redirect_to user.profile_url 
    else 
     user = User.new 
     user.omniauth(omniauth) 
     if user.save! 
     sign_in_and_redirect_user(:user, user.profile) 
     else 
     session[:omniauth] = omniauth.except('extra') 
     redirect_to new_user_registration_url 
     end 
    end 
    end 

    def destroy 
    @authentication.destroy 
    respond_to do |format| 
     format.html { redirect_to root_path } 
     format.json { head :no_content } 
    end 
    end 

    private 
    # Use callbacks to share common setup or constraints between actions. 
    def set_authentication 
     @authentication = current_user.authentications.find(params[:id]) 
    end 

końcowy

kontroler

Zgłoszenia:

class Users::RegistrationsController < Devise::RegistrationsController 
    #before_filter :check_permissions , :only => [ :new, :create, :cancel ] 
    #skip_before_filter :require_no_authentication 
    # before_action :configure_permitted_parameters, if: :devise_controller? 

    def check_permissions 
    authorize! :create, resource 
    end 

    def index 
    if params[:approved] == "false" 
     @users = User.find_all_by_approved(false) 
    else 
     @users = User.all 
    end 
    end 

    def create 
    super 
    session[:omniauth] = nil unless @user.new_record? 
    end 

    # THIS IS A SUGGESTION FROM SITEPOINT TUTORIAL 
    # protected 

    # def configure_permitted_parameters 
    #  devise_parameter_sanitizer.for(:sign_up) << [:first_name, :last_name] 
    # end 


    private 
    def user_params 
      params.require(:user).permit(:first_name, :last_name, :email, :password) 
    end 

    def build_resource(*args) 
     super 
     if session[:omniauth] 
     @user.apply_omniauth(session[:omniauth]) 
     @user.valid? 
     end 
    end 

end 

użytkownika.rb ma

devise 
:omniauthable, :omniauth_providers => [:facebook, :linkedin, :twitter, :google_oauth2 ] 


has_many :authentications, :dependent => :delete_all 


def apply_omniauth(omniauth) 
     self.email = auth['extra']['raw_info']['email'] 
     authentications.build(:provider => omniauth['provider'], :uid => omniauth['uid'], :token => auth['credentials']['token']) 
    end 

def password_required? 
    (authentications.empty? || !password.blank?) && super 
end 

W mojej routes.rb mam:

devise_for :users, 
      :controllers => { 
       :registrations => "users/registrations", 
       :omniauth_callbacks => "users/authentications" 
       # :omniauth_callbacks => 'users/omniauth_callbacks', 
      } 
    get '/auth/:provider/callback' => 'users/authentications#create' 
    get '/sign_out', :to => 'users/authentications#destroy'   

W moim omniauth.rb mam:

require 'omniauth-facebook' 
require 'omniauth-google-oauth2' 
require 'omniauth-twitter' 



OmniAuth.config.logger = Rails.logger 

Rails.application.config.middleware.use OmniAuth::Builder do 
    provider :twitter, ENV['TWITTER_KEY'], ENV['TWITTER_SECRET'] 
end 

Rails.application.config.middleware.use OmniAuth::Builder do 
    provider :facebook, ENV['FACEBOOK_ID'], ENV['FACEBOOK_KEY'], 
    :scope => 'public_profile', info_fields: 'id,first_name,last_name,link,email', 
    :display => 'popup', 
    :client_options => {:ssl => {:ca_file => '/usr/lib/ssl/certs/ca-certificates.crt'}} 

end 

Rails.application.config.middleware.use OmniAuth::Builder do 
    provider :google_oauth2, ENV['YT_CLIENT_ID'], ENV['YT_CLIENT_SECRET'], 
      scope: 'profile', image_aspect_ratio: 'square', image_size: 48, 
      # {name: "google_login", approval_prompt: ''}, 
      access_type: 'online' 
      #ENV["GOOGLE_APP_ID"], ENV["GOOGLE_APP_SECRET"] 
# { 
#   :name => "google", 
#   :scope => "userinfo.email, userinfo.profile, plus.me, http://gdata.youtube.com", 
#   :prompt => "select_account", 
#   :image_aspect_ratio => "square", 
#   :image_size => 50 
#  } 

end 

Rails.application.config.middleware.use OmniAuth::Builder do 
    if Rails.env == 'production' 
    key = ENV["LINKEDIN_PRODUCTION_KEY"] 
    secret = ENV["LINKEDIN_PRODUCTION_SECRET"] 
    else 
    key = "LINKEDIN_DEV_ID" 
    secret = "LINKEDIN_DEV_KEY" 
    end 

    provider :linkedin, key, secret, 
    :scope => "r_basicprofile r_emailaddress", 
    :field => ["id", "email-address", "first-name", "last-name" ], 
    :client_options => {:ssl => {:ca_file => '/usr/lib/ssl/certs/ca-certificates.crt'}} 
end 

w moim nowym widokiem rejestracji/sesji, mam:

<% if devise_mapping.omniauthable? %> 
          <%= link_to icon('facebook', id: 'facebookauth'), user_omniauth_authorize_path(:facebook) %> 

          <%= link_to icon('google', id: 'googleauth'), user_omniauth_authorize_path(:google_oauth2) %> 

          <%= link_to icon('linkedin', id: 'linkedinauth'), user_omniauth_authorize_path(:linkedin) %> 

          <%= link_to icon('twitter', id: 'twitterauth'), user_omniauth_authorize_path(:twitter) %> 
         <% end %> 

Myślę, że ma to coś wspólnego z n ot o nazwanych strategiach kontrolerem autentykacji. W innych samouczkach ustawiłem następujące (teraz skomentowałem z kontrolera, ponieważ obecnie jest używana metoda o nazwie apply_omniauth).

# def facebook 
# # @user = User.find_for_facebook_oauth(request.env["omniauth.auth"]) 
# # if @user.persisted? 
# #  # @user.send_admin_mail 
# #  # @user.send_user_welcome_mail 

# #  sign_in @user, :event => :authentication #this will throw if @user is not activated 

# #  if @user.profile 
# #  redirect_to profile_path(@user.profile) 
# #  else 
# #  redirect_to new_profile_path 
# #  end 

# #  # sign_in_and_redirect @user, :event => :authentication #this will throw 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 root_path 
# # end 
# # end 


# # def linkedin 
# # @user = User.find_for_linkedin_oauth(request.env["omniauth.auth"]) 

# # if @user.persisted? 
# #  # @user.send_admin_mail 
# #  # @user.send_user_welcome_mail 

# #  sign_in @user, :event => :authentication 

# #  if @user.profile 
# #  redirect_to profile_path(@user.profile) 
# #  else 
# #  redirect_to new_profile_path 
# #  end 
# #  # set_flash_message(:notice, :success, :kind => "LinkedIn") if is_navigational_format? 
# # else 
# #  session["devise.linkedin_data"] = request.env["omniauth.auth"] 
# #  redirect_to root_path 
# # end 
# # end 


# # def twitter 
# # begin 
# #  @user = User.from_omniauth(request.env['omniauth.auth']) 
# #  session[:user_id] = @user.id 
# #  flash[:success] = "Welcome, #{@user.name}!" 
# # rescue 
# #  flash[:warning] = "There was an error while trying to authenticate you..." 
# # end 
# # redirect_to new_profile_path #root_path 
# # end 

# # # 
# def google_oauth2 
#  # You need to implement the method below in your model (e.g. app/models/user.rb) 
#  @user = User.find_for_google_oauth2(request.env["omniauth.auth"], current_user) 

#  if @user.persisted? 
#   sign_in @user, :event => :authentication #this will throw if @user is not activated 
#   if @user.profile 
#   redirect_to profile_path(@user.profile) 
#   flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Google" 
#   else 
#   redirect_to new_profile_path 
#   end 

#  else 
#  session["devise.google_data"] = request.env["omniauth.auth"] 
#  redirect_to new_user_registration_url 
#  end 
# end 

Zanim całkowicie rowu szyn oddanych setup, czy istnieje sposób mogę wskazać obecną strukturę w kierunku wymienionych dostawców stosując kod już mam?

kolejna próba:

więc porzuciła RailsCast. Próbowałem wykonać ten samouczek:

http://willschenk.com/setting-up-devise-with-twitter-and-facebook-and-other-omniauth-schemes-without-email-addresses/ 

Jestem zdezorientowany przez odniesienie do dodania nowej "klasy" o nazwie FormUser. Zrobiłem nowy model o nazwie form_user.rb i dodałem zawartość zgodnie z opisem. Używam Rails 4. Nie wiem, co oznacza atto-accessor, ale mam go w moim pliku, jak pokazano. Nie mam odpowiedniego kontrolera. Nie mam również skojarzeń zdefiniowanych w moim modelu użytkownika (do którego myślę, że należy).

Zresztą Śledzę konfigurację i teraz uzyskać ten błąd:

TypeError 
superclass mismatch for class OmniauthCallbacksController 

To samo dla każdej ze strategii określonych w mojej aplikacji.

Czy ktoś widział ten konkretny błąd & ma jakieś wskazówki, jak go rozwiązać?

Jedyną różnicą między moją konfiguracją a samouczkiem jest to, że w kontrolerach mam folder o nazwie użytkownicy, w tym przypadku mam kontroler rejestracji i kontroler omniauth_callbacks. Moje trasy zostały dostosowane w celu odzwierciedlenia tej warstwy.

devise_for :users, class_name: 'FormUser', 
      :controllers => { 
       :registrations => "users/registrations", 
       # :omniauth_callbacks => "users/authentications" 
       :omniauth_callbacks => 'users/omniauth_callbacks', 
      } 
    get '/auth/:provider/callback' => 'users/authentications#create' 
    get '/authentications/sign_out', :to => 'users/authentications#destroy' 


    devise_scope :user do 
    get '/users/auth/:provider/upgrade' => 'users/omniauth_callbacks#upgrade', as: :user_omniauth_upgrade 
    get '/users/auth/:provider/setup', :to => 'users/omniauth_callbacks#setup' 
    end 
+0

Co robisz, gdy pojawi się błąd? Klikasz w łącze lub dzieje się to podczas połączenia zwrotnego? – Stewart

+0

Klikam na link do nowej rejestracji z Facebookiem itp. (wszystkie strategie dają takie same error) – Mel

+0

Z pamięci miałem problemy z oddzwanianiem do localhost. Zmień wszystkie domeny wywołania zwrotnego w twoich usługach na prawdziwy adres URL. Powinien to być FQN, którego zamierzałeś użyć.Następnie zaktualizuj plik hosts i wskaż tę nazwę z powrotem do lokalnego hosta. Przetestuj ponownie. – Stewart

Odpowiedz

1

Jeśli ktoś rozdziera sobie włosy z głowy próbując dowiedzieć się tego - nie mam odpowiedź dla jak to zrobić, ale wiem, że Railscasts są tak stare, że nie są użyteczne. Istnieje kilka części powyższego kodu, które nie pasują do konfiguracji gem. Po tych samouczkach nie pomoże. Przez ostatnie 1,5 roku starałem się śledzić co najmniej 20 różnych tutoriali i jeszcze nie znalazłem takiego, który mógłbym dostać do pracy. Błędy w castingu to przekierowanie (nie wymaga więcej odniesienia do "użytkownika" wśród wielu innych.) Rezygnacja, jeśli polegasz na Rails Cast. Byłbym bardzo wdzięczny, gdyby ktoś miał jakikolwiek wgląd w to, gdzie znaleźć AKTUALNY samouczek: