I got a question will trying to use omniauth-facebook with devise
I followed this railscast video(just substitute twitter with facebook) and was able to get it work.
However, I would like to customize my routes a little bit, so this is what I did:
config/routes.rb
devise_for :users, path: 'accounts',
controllers: { omniauth_callbacks: "omniauth_callbacks" },
path_names: { sign_in: "login", sign_out: "logout", sign_up: "signup" }
app/controllers/omniauth_callbacks_controller.rb
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def all
user = User.from_omniauth(request.env["omniauth.auth"])
if user.persisted?
flash.notice = "Successfully signed in via #{request.env["omniauth.auth"].provider}!"
sign_in_and_redirect user
else
session["devise.user_attributes"] = user.attributes
redirect_to new_user_registration_url
end
end
alias_method :facebook, :all
end
as I expected, in my url "users/..." was changed to "accounts/...", but when I tried to login via facebook, I got this error:
Routing Error
No route matches [GET] "/users/auth/facebook/callback"
after play around with it, I got around it by adding this line:
config/routes.rb
get '/users/auth/facebook/callback', to: redirect('/accounts/auth/facebook/callback')
It works fine now, but I think there must be better solution.
Is there any way to change the returned callback url from /users/auth/facebook/callback to /accounts/auth/facebook/callback ???
Thanks!
Problems Solved, I forgot to set window.location in Javascript code.
After I changed my window.location, it's working fine
Related
I'm using 'omniauth-google-oauth2' for sign in with google and follow all instruction here carefully
https://github.com/plataformatec/devise/wiki/OmniAuth%3A-Overview
but i have error above.
my routes
devise_for :users, :controllers => {
:omniauth_callbacks => "users/omniauth_callbacks"
}
devise.rb code
config.omniauth :google_oauth2, "863625299460- 420n6c7lvad91dfvko60uamtvtr6huhf.apps.googleusercontent.com", "dcvA2aZRZi27KCQjWTYP30pw", { access_type: "offline", approval_prompt: "" }
omniauth callback controller code
def google_oauth2
##user = User.find_for_google_oauth2(request.env["omniauth.auth"], current_user)
binding.pry #control not coming here
end
i have error below after callback. see screenshot
https://github.com/zquestz/omniauth-google-oauth2/issues/52
This looks like a route issue. If you do "rake routes | grep auth" what do you see?
I had exactly the same problem you described. Make sure you require the omniauth-google-oauth2 gem in config/initializers/deviser.rb
# ==> OmniAuth
# Add a new OmniAuth provider. Check the wiki for more information on setting
# up on your models and hooks.
require "omniauth-google-oauth2"
config.omniauth :google_oauth2, ENV["GOOGLE_KEY"], ENV["GOOGLE_SECRET"],
{ access_type: "offline", approval_prompt: "force" }
I've added the entire portion of my devise.rb file to provide context.
It's very late but this answer might be useful for others
If you are using devise for authentication then devise by default generates routes in the route file devise_for :users and your omniouth_callback route should be above the default devise route so that it overwrites default devise route.
devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks"}
devise_for :users
I've followed the Devise wiki to switch the login route from /users/sign_in to /login. My routes file looks like this:
devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks" }
devise_scope :user do
get '/login' , :to => 'devise/sessions#new' , :as => :login
delete '/logout', :to => 'devise/sessions#destroy', :as => :logout
end
and my user model has this
class User < ActiveRecord::Base
devise :omniauthable, :database_authenticatable
end
I have a common scenario where a user is logged out, tries to access a restricted page, and then redirected to log himself in.
However, when that user is redirected, devise sends them to /users/sign_in path instead of /login.
The only way I could make the redirection to the /login url work is by adding this to the top of my routes.rb:
match "/users/sign_in" => redirect('/login')
which adds a redirect to my application, which in turn messes up tests - whenever I do something like this:
current_url.should == login_path
I get an error saying the expected path was "/login" and the actual was "/users/sign_in".
Did I miss something here - what's an elegant way to work around it? thanks.
side note
I only use :omniauthable to authenticate, but I added :database_authenticatable to devise configuration to force it to go to a dedicated login page.
Otherwise, devise always directs to the root path, so it would seem. If you know of a better way to do that, please - chime in.
I'm working on a Rails-based API. I recently started attempting to version it. (I'm using the Versionist gem, in case it matters) One version ('v2') uses Devise and Omniauth to authenticate users through Facebook/Twitter.
I want all the routes associated with this version to have the appropriate version prefix (so users/:username/foo becomes v2/users/:username/foo, etc.), but I've already found out that putting devise_for inside the api_version block prevents the Devise helpers (current_user, user_signed_in?, etc.) from working, so it continues to live outside the block:
routes.rb:
devise_for :user, :path => '', :controllers => {:omniauth_callbacks => 'users/omniauth_callbacks'}, :skip => [:registrations, :confirmations, :sessions, :passwords]
api_version(:module => "V2", :path=>"v2") do
resources :authentications, :only => [:update, :destroy]
devise_scope :user do
post 'login' => 'sessions#create', :as => 'user_session'
get 'logout' => 'sessions#destroy'
post 'password' => 'devise/passwords#create'
put 'password' => 'devise/passwords#update'
end
end
Everything seemed great... except the Devise-generated omniauth routes:
rake routes output:
user_omniauth_authorize /auth/:provider(.:format)
user_omniauth_callback /auth/:action/callback(.:format)
Now, some google-fu revealed that there's a devise configuration setting for this, so I added the following to our devise initializer (config/initializers/devise.rb):
Devise.setup do |config|
config.omniauth_path_prefix = 'v2/auth'
end
Now, rake routes produces paths that look sensible:
user_omniauth_authorize /v2/auth/:provider(.:format) v2/users/omniauth_callbacks#passthru {:provider=>/(?!)/}
user_omniauth_callback /v2/auth/:action/callback(.:format) v2/users/omniauth_callbacks#(?-mix:(?!))
However, when I attempt to access this route by calling api.localhost/v2/auth/facebook, I get a routing error:
ActionController::RoutingError (No route matches [GET] "/v2/auth/facebook")
Any idea what's going on here?
You are missing the provider name in the routes so they don't match the facebook part in /v2/auth/facebook. The correct route destination should look something like v2/users/omniauth_callbacks#(?-mix:facebook).
Have you specified the provider in the user model?
devise_for ..., :omniauthable, :omniauth_providers => [:facebook]
For the record, I'm using Rails 3.2 and Devise 3.0 and the altered route seems to work (I haven't gone further yet to see if something else will break).
I am trying to create the user registration views and model on my website but I am having a small issue :
I am using devise and omniauth to get the facebook connect features working and it works,
But I want my facebook users when they sign in the first time to create their password,
That is also working, I redirect them to the filled sign up form and they only have to enter their password. But I want them to go to a second "sign_up form" named /views/registrations/new_facebook.html.erb where they can only enter their password and I will also add some other information,
I created the correct view and tested it but I have no idea how to create the correct routes to bypass Devise default
match '/facebook' => 'registrations#new', :as => 'new_facebook_user_registration'
I believe the issue is with match because that's what's not recognised,
If anyone can help me that would be great thanks,
I added my controller code for omniauth :
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def all
user = User.from_omniauth(request.env["omniauth.auth"])
if user.persisted?
flash[:success] = "Welcome back"
sign_in_and_redirect user
else
session["devise.user_attributes"] = user.attributes
redirect_to new_facebook_user_registration_url
end
end
alias_method :facebook, :all
end
How can I make the redirect_to new_facebook_user_registration_url actually work ?
devise_scope :user do
match "registrations/new_facebook" => "registrations#new_facebook"
end
That's the solution I copied in the registrations controller the new method and named it new_facebook and now everything is working as expected !
I think the issue is that you're not overriding the devise method that redirects to that path. Also according to the devise docs your routes should be set up with a "devise_for" call.
Here's the wiki page describing how to do what you are asking to do, although you may need a bit of custom logic to deal with cases that aren't facebook signups.
https://github.com/plataformatec/devise/wiki/How-To:-Redirect-to-a-specific-page-on-successful-sign-up-(registration)
Some example code from that page:
class RegistrationsController < Devise::RegistrationsController
protected
def after_sign_up_path_for(resource)
'/an/example/path'
end
end
and the one for routes:
devise_for :users, :controllers => { :registrations => "registrations" }
I'm trying to implement facebook authentication in my app following this guide
I've followed all the steps but get the following error after hitting login.
Unknown action
The action 'facebook' could not be found for Devise::OmniauthCallbacksController
I've created the file omniauth_callbacks_controller in controllers/users. It has a facebook method defined. Any idea how I should debug?
Adding my routes file -
Myapp::Application.routes.draw do
get "static_pages/home"
get "static_pages/help"
get "static_pages/about"
devise_for :users do
resources :posts
end
root :to => 'static_pages#home'
devise_for :users, controllers: {omniauth_callbacks: "omniauth_callbacks"}
end
If you look at the guide it specifies this line for your routes file:
devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks" }
where you have:
devise_for :users, controllers: {omniauth_callbacks: "omniauth_callbacks"}
see the difference?
I am assuming that your users will be able to login and logout, edit profile, register with facebook or register with email and also you may add Confirmable to devise if you want. You should have extra columns in users table. Something like adding extra fields into your user model first.
rails g migration AddFieledsToUser provider:string uid:string image:string
then run rails db:migrate
Check your users table ensure you have these 3 columns above
Also I am assuming that you you have correctly configured initializers/devise.rb like so: config.omniauth :facebook, 'APP_ID', 'APP_SECRET_KEY', scope: 'email', info_fields: 'email, name' after you've properly created the facebook app. Also assuming you have properly created and configured your omniauth_callbacks_controller.rb based on the gems gem 'omniauth', '~> 1.6' and gem 'omniauth-facebook', '~> 4.0' in your gem file successfully. Just make sure you have all these steps done.
In your routes.rb you can add this:
devise_for :users,
path: '',
path_names: {
sign_in: 'login',
sign_out: 'logout',
edit: 'profile',
sign_up: 'registration'
},
controllers: {
omniauth_callbacks: 'omniauth_callbacks',
}
I think this is the part you have missed. You can also name the routes whatever you want. Just saying.
I ran into a similar problem with tutorials. Check the capitalization of
F in facebook in users/omniauth_callbacks_controller.rb I was using a capital "Facebook" but it was looking for lowercase "facebook"