LoadError in OmniauthCallbacksController#passthru (with devise/stripe connect) - ruby-on-rails

Trying to implement Stripe Connect, and am getting the following error when I click the "connect to stripe" button.
The action 'passthru' could not be found for OmniauthCallbacksController
users/omniauth_callbacks_controller.rb
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def stripe_connect
#user = current_user
if #user.update_attributes({
provider: request.env["omniauth.auth"].provider,
uid: request.env["omniauth.auth"].uid,
access_code: request.env["omniauth.auth"].credentials.token,
publishable_key: request.env["omniauth.auth"].info.stripe_publishable_key
})
# anything else you need to do in response..
sign_in_and_redirect #user, :event => :authentication
set_flash_message(:notice, :success, :kind => "Stripe") if is_navigational_format?
else
session["devise.stripe_connect_data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
end
models/user.rb
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :omniauthable, :omniauth_providers => [:stripe_connect]
routes.rb
devise_for :users, controllers: { registrations: 'users/registrations', :omniauth_callbacks => "users/omniauth_callbacks" }
gemfile.rb
gem 'omniauth-stripe-connect'
initializers/stripe.rb
Rails.configuration.stripe = {
:publishable_key => ENV['PUBLISHABLE_KEY'],
:secret_key => ENV['SECRET_KEY']
}
Stripe.api_key = Rails.configuration.stripe[:secret_key]
initializers/devise.rb
config.omniauth :stripe_connect,
ENV['STRIPE_CONNECT_CLIENT_ID'],
ENV['STRIPE_SECRET_KEY'],
:scope => 'read_write',
:stripe_landing => 'register'
button link:
<%= link_to image_tag('blue-on-light.png'), user_stripe_connect_omniauth_authorize_path(:stripe_connect) %>
As I understand it with my noob Ruby mind, I need to define 'passthru'? how do I define it though? when I enter:
def passthru
end
the link doesn't work / the page reloads itself. Haven't been able to find a solution on here. What am I missing?
EDIT:
Changed my connect to stripe link to:
<%= link_to image_tag('blue-on-light.png'), "/users/auth/stripe_connect" %>
The link takes me to the connect to stripe page, but when I click the "connect to stripe" button, the page cant be found, and doesn't load or redirect.

Can you try changing
# app/controllers/omniauth_callbacks_controller.rb
class OmniauthCallbacksController < ApplicationController
def stripe_connect
....
to
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def stripe_connect
#user = User.find_for_stripe_connect(request.env['omniauth.auth'], current_user)
set_notice_and_redirect
end
private
def set_notice_and_redirect
if #user.persisted?
flash[:notice] = 'Successfully signed in'
set_flash_message(:notice, :success, :kind => "Stripe") if is_navigational_format?
else
session["devise.stripe_connect_data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
end
and in your user model
# Checks if user exists, otherwise create it
def self.find_for_stripe_connect(access_token, _ = nil)
data = access_token.info
user = User.where(email: data['email']).first_or_create(
email: data['email'],
password: Devise.friendly_token[0, 20],
provider: request.env["omniauth.auth"].provider,
uid: request.env["omniauth.auth"].uid,
access_code: request.env["omniauth.auth"].credentials.token,
publishable_key: request.env["omniauth.auth"].info.stripe_publishable_key
)
user
end
and also sing in path
<%= link_to image_tag('blue-on-light.png'), user_stripe_connect_omniauth_authorize %>
I think you don't need to define a passthru action. If you see the below two in the routes it can work. Authorize path is for redirecting user to stripe and callback is for redirecting user from stripe back to your site
$ rake routes
user_stripe_connect_omniauth_authorize /auth/stripe_connect(.:format) ....
user_stripe_connect_omniauth_callback /auth/stripe_connect/callback(.:format) ....

Related

Omniauth-facebook with Devise: "Missing passthru" errors

I have Devise authentication installed with no problems. Now I'm trying to add an option to log in with Facebook, using Omniauth-facebook.
I followed the instructions in this guide, but I'm getting errors about missing "Passthru" documentation, when visiting the url localhost:3000/auth/facebook.
Here's the first error I got:
Unknown action
The action 'passthru' could not be found for RegistrationsController
I tried a bandaid fix by just adding an empty "passthru" action to my controller:
def passthru
end
And that resolved that error, but I got a different one in return:
Template is missing
Missing template registrations/passthru, devise/registrations/passthru, devise/passthru, application/passthru with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :raw, :ruby, :jbuilder, :coffee]}. Searched in: * "/home/user/project/app/views" * "/home/user/.rvm/gems/ruby-2.0.0-p648#railstutorial_rails_4_0/gems/devise-3.5.2/app/views"
I tried creating a "passthru.html.erb" in the stated folders, but that error remained. In any case, I think these errors are emblematic of a deeper problem.
Has anyone else run into this problem? All I could find on it was this SO question, but none of the answers were helpful.
My code so far:
Gemfile
gem 'devise'
gem 'omniauth-facebook'
gem 'omniauth'
routes.rb
devise_for :members, controllers: { registrations: 'registrations', omniauth_callbacks: 'registrations' }
member.rb
devise :database_authenticatable, :registerable,
:omniauthable, :omniauth_providers => [:facebook]
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |member|
member.email = auth.info.email
member.password = Devise.friendly_token[0,20]
member.title = auth.info.name
end
end
registrations_controller.rb
def facebook
#member = Member.from_omniauth(request.env["omniauth.auth"])
if #member.persisted?
sign_in_and_redirect #member, :event => :authentication
set_flash_message(:notice, :success, :kind => "Facebook") if is_navigational_format?
else
session["devise.facebook_data"] = request.env["omniauth.auth"]
redirect_to new_member_registration_url
end
end
def failure
redirect_to root_path
end
def passthru
end
initializers/devise.rb
config.omniauth :facebook, "<app_id>", "<app_secret>"
Try this :
Update GemFile:
gem 'omniauth-facebook'
gem 'omniauth'
Goto rails_apps/yourapp/config/initializers/devise.rb
Devise.setup do |config|
config.omniauth :facebook, "KEY", "SECRET"
end
Update the User Model
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:omniauthable, :omniauth_providers => [:facebook]
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.provider = auth.provider
user.uid = auth.uid
user.email = auth.info.email
user.password = Devise.friendly_token[0,20]
end
end
end
Goto : rails_apps/yourapp/config/routes.rb
Rails.application.routes.draw do
devise_for :users
resources :users
end
Edit in View
<%= link_to "Sign in with Facebook", "/auth/facebook", id: "sign_in" %>
Passthru is a relic from omniauth update your gems of devise omniauth and so on .
there is a controller called omiauth_callback this is the one makes noizes ;P.(may help you trace the problem's source)
If you create a method in controller like so :
def passthru
end
You HAVE TO create a view with(even empty), or redirection :get inspired by ajax techniques to bypass html rendering .
Hope it send you on the way of problem solving .
try also theses routes :
```
user_omniauth_authorize /users/auth/:provider(.:format) sessions#passthru {:provider=>/facebook|twitter|google/}
user_omniauth_callback /users/auth/:action/callback(.:format) sessions#(?-mix:facebook|twitter|google)
```
You can create another controller for Omniauth callback
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def facebook
#user = User.from_omniauth(request.env['omniauth.auth'])
if #user.persisted?
sign_in_and_redirect #user, :event => :authentication
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 after_sign_in_path_for(resource)
super resource
end
end
you need to reset your routes as
devise_for :members, :controllers => {:registrations => "members/registrations", :omniauth_callbacks => 'omniauth_callbacks'}
As i could remember you need not to use :omniauth_providers => [:facebook] in your member.rb
Now you can add a button in your sign_up page or instead include the below code in your devise/shared/_links.html.erb, because it will be available in your sign_in form also.
<%- if devise_mapping.omniauthable? %>
<%- resource_class.omniauth_providers.each do |provider| %>
<%= link_to "Sign up with #{provider.to_s.titleize}", omniauth_authorize_path(resource_name, provider), class: "btn btn-default navbar-btn" %><br />
<% end -%>
<% end -%>
you also need to configure devise in initializers
In your /config/initializers/devise.rb
config.omniauth :facebook, "App ID", "App Secret", scope: 'email', info_fields: 'email,name'
Please go through this simplest tutorial for Sing_up with facebook Link
Try this .........
config/initializers/devise.rb
config.omniauth :facebook, ENV["FACEBOOK_KEY"], ENV["FACEBOOK_SECRET"], { :scope => 'email, offline_access'}
config/routes.rb
devise_for :members, controllers: { registrations: 'registrations', omniauth_callbacks: "omniauth_callbacks" }
app/models/member.rb
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :omniauthable
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |member|
member.email = auth.info.email
member.password = Devise.friendly_token[0,20]
member.title = auth.info.name
end
end
app/controllers/omniauth_callbacks_controller.rb
skip_before_filter :authenticate_user!
def facebook
p env["omniauth.auth"]
user = User.from_omniauth(env["omniauth.auth"])
if user.persisted?
flash[:notice] = "You are in..!!!"
sign_in_and_redirect(user)
else
session["devise.user_attributes"] = user.attributes
redirect_to new_user_registration_url
end
end
def failure
#handle you logic here..
#and delegate to super.
super
end
Hope this will work for you.
I think the problem is always on the button or the anchor, so use this
<%= link_to user_facebook_omniauth_authorize_path, method: :post do %>
login with facebook
<% end %>

ERR_TOO_MANY_REDIRECTS logging in with OmniAuth/Devise/Rails

I'm attempting to add Facebook login to my Rails 4 site following these instructions:
https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview
I'm currently using Devise and Pundit for authorization and authentication. Despite having followed the instructions to my best ability, I'm getting an error. When I click my "Login with Facebook" button, a window pops up that asks for email/password, and when I submit that info, I get an error page that reads:
[MyApp.com] page isn’t working
[MyApp.com] redirected you too many times.
Try:
Reloading the page
Clearing your cookies ERR_TOO_MANY_REDIRECTS
It seems like somehow I've introduced a redirect loop, but I don't really understand the data flow, so it's hard to find where I've gone wrong.
Here's my routes.rb:
Rails.application.routes.draw do
get 'home/index'
devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks", sessions: "sessions" }
resources :movies
root 'home#index'
end
omniauth_callbacks_controller.rb:
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
before_filter :authenticate_user, :except => [:new, :create, :destroy]
def facebook
# You need to implement the method below in your model (e.g. app/models/user.rb)
#user = User.from_omniauth(request.env["omniauth.auth"])
if #user.persisted?
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 new_user_registration_url
end
end
def failure
redirect_to root_path
end
end
OmniAuth's configuration in config/initializers/devise.rb:
config.omniauth :facebook, '[APP ID]', '[APP SECRET]', callback_url: "https://#{ENV['C9_HOSTNAME']}/users/auth/facebook",
:client_options => {:ca_file => '/usr/lib/ssl/certs/ca-certificates.crt'}
My user model (user.rb):
class User < ActiveRecord::Base
rolify
# Include default devise modules. Others available are:
# :confirmable, :lockable, and :timeoutable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:omniauthable, :omniauth_providers => [:facebook]
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.email = auth.info.email
user.password = Devise.friendly_token[0,20]
end
end
def self.new_with_session(params, session)
super.tap do |user|
if data = session["devise.facebook_data"] && session["devise.facebook_data"]["extra"]["raw_info"]
user.email = data["email"] if user.email.blank?
end
end
end
end
And the link in my view (using HAML):
%button
= link_to "Log in with Facebook", user_omniauth_authorize_path(:facebook)
I've just had this exact problem too! After you recieved this error, were you able to reload the page and it had actually logged you in? If so, then that's what I had. The log in worked - but the redirects weren't good.
Have you added in the function after_sign_in_path_for(resource) to the application_controller.rb that redirects the page after login? I had and that's why the redirects were occuring.
My solution was to fixed the if statement to include the right referrer. I just added in || request.referer.include?("google"), of course you may have to change it to account for 'facebook' in the referrer url.
def after_sign_in_path_for(resource)
sign_in_url = new_user_session_url
if request.referer == sign_in_url || request.referer.include?("google")
super
goals_path
else
stored_location_for(resource) || request.referer || root_path
end
end
Now... if you haven't used that function then my answer will be useless to you. Good luck.

Completed 401 Unauthorized Error for omniauth devise in Rails

I am trying to add login through gmail feature to my application.
I used 'omniauth' and 'omniauth-google-oauth2' gems,Here is my code
User.rb
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,:omniauthable
def self.find_for_google_oauth2(access_token, signed_in_resource=nil)
data = access_token.info
user = User.where(:provider => access_token.provider, :uid => access_token.uid ).first
if user
return user
else
registered_user = User.where(:email => access_token.info.email).first
if registered_user
return registered_user
else
user = User.create(name: data["name"],
provider:access_token.provider,
email: data["email"],
uid: access_token.uid ,
password: Devise.friendly_token[0,20],
)
end
end
end
devise.rb
require 'omniauth-google-oauth2'
config.omniauth :google_oauth2, "APP_ID", "APP_SECRET", { access_type: "offline", approval_prompt: "" }
replaced APP_ID with my client_id and APP_SECRET with my client_secret
routes.rb
devise_for :users, :controllers => { : omniauth_callbacks => "omniauth_callbacks" }
omniauth_callbacks_controller.rb
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def google_oauth2
#user = User.find_for_google_oauth2(request.env["omniauth.auth"], current_user)
if #user.persisted?
flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Google"
sign_in_and_redirect #user, :event => :authentication
else
session["devise.google_data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
authorised redirect URI
http://localhost:3000/users/auth/google_oauth2/callback
When I try to login it gives
Started GET "/users/auth/google_oauth2/callback?state=fb1921cc2fd051c677bb0058e21e17fbaa028fce2e7eb669&code=4/g2xXVC2arLfYzWGqnswcIuwkDarfdW1ZzPSJRIcdUqw" for 127.0.0.1 at 2015-10-27 16:11:31 +0530
I, [2015-10-27T16:11:31.311428 #8223] INFO -- omniauth: (google_oauth2) Callback phase initiated.
Processing by OmniauthCallbacksController#google_oauth2 as HTML
Parameters: {"state"=>"fb1921cc2fd051c677bb0058e21e17fbaa028fce2e7eb669", "code"=>"4/g2xXVC2arLfYzWGqnswcIuwkDarfdW1ZzPSJRIcdUqw"}
Completed 401 Unauthorized in 0ms
Is there anything wrong in my code,Thanks in advance.
In Omniauth Call Back Controller , try the below code:
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def google_oauth2
#user = User.find_for_google_oauth2(request.env["omniauth.auth"], current_user)
if #user.persisted?
flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Google"
sign_in_and_redirect #user, :event => :authentication, bypass => true
else
session["devise.google_data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
I just added bypass => true

I defined a controller method for google_oauth2 for devise, but it's still missing

When I try to authenticate, I get the message:
"Not found. Authentication passthru."
I added an action_missing method to get a clue: when it's called, it logs:
Parameters: {"provider"=>"google_oauth2"}
So it would appear that I'm getting a complaint that I'm missing the very method that I've defined. Why is my action missing when it's defined?
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def google_oauth2
#user = User.from_omniauth(request.env["omniauth.auth"])
if #user.persisted?
flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Google"
sign_in_and_redirect #user, :event => :authentication
else
session["devise.google_data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
def action_missing(provider)
logger.debug provider
end
end
devise.rb:
config.omniauth :google_oauth2,
'my',
'secret',
{
:name => "google",
:scope => 'email, profile',
:prompt => 'select_account',
:image_aspect_ratio => 'square',
:image_size => 50
}
User.rb:
class User < ActiveRecord::Base
devise :omniauthable, :omniauth_providers => [:google_oauth2]
def self.from_omniauth(access_token)
data = access_token.info
user = User.where(:email => data["email"]).first
# Uncomment the section below if you want users to be created if they don't exist
# unless user
# user = User.create(name: data["name"],
# email: data["email"],
# password: Devise.friendly_token[0,20]
# )
# end
user
end
end
If you provide :name to your config settings you have to call it from the given name. Also your Authorized redirect URIs will have the name "google" as you specify here.
I found my mistake, someone else may find it edifying:
in devise.rb, I had:
{
:name => 'google', <====== BAD IDEA!
:scope => 'email, profile',
:prompt => 'select_account',
:image_aspect_ratio => 'square',
:image_size => 50
}
the first item, the :name, was copied from another omniauth tutorial. It seems to be a very bad idea. Removing it made things go.

Google+ Sign Up with Devise and Rails (google_oauth2)

I'm getting the following error when trying to sign in through google+ using the google_oauth2 gem.
undefined method `find_for_google_oauth2' for #<Class:0x007ff70a337148>
Here's the three files I've altered for sign up.
user.rb
def google_oauth2
user = User.from_omniauth(request.env["omniauth.auth"])
if user.persisted?
flash.notice = "Signed in Through Google!"
sign_in_and_redirect user
else
session["devise.user_attributes"] = user.attributes
flash.notice = "You are almost Done! Please provide a password to finish setting up your account"
redirect_to new_user_registration_url
end
end
omniauth_callbacks_controller.rb
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?
flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Google"
sign_in_and_redirect #user, :event => :authentication
else
session["devise.google_data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
and I've added config.omniauth :google_oauth2 in my devise.rb file.
routes.rb
devise_for :users, :controllers => { :registrations => "registrations", :sessions => "sessions", :omniauth_callbacks => "users/omniauth_callbacks" }
You are calling find_for_google_oauth2 from the omniauth_callbacks_controller, but you are using the wrong method name google_oauth2. You should replace google_oauth2 with find_for_google_oauth2.
And it seems like the code in user.rb is incorrect because it contains the controller code. Do you see it looks exactly the same like your controller code? :)
Correct code for user.rb
def self.find_for_google_oauth2(access_token, signed_in_resource=nil)
data = access_token.info
user = User.where(:email => data["email"]).first
# Uncomment the section below if you want users to be created if they don't exist
# unless user
# user = User.create(name: data["name"],
# email: data["email"],
# password: Devise.friendly_token[0,20]
# )
# end
user
end
Read more here: https://github.com/zquestz/omniauth-google-oauth2#devise

Resources