omniauth auth/failure message=invalid_credentials - ruby-on-rails

I am using omiauth with ROR and i get the following error,
omniauth auth/failure message=invalid_credentials,
I am able to connect with linkedin, i am asked for user credentials after giving everything the page redirect is happening and i get the above error.
Here is my callback:
class SessionsController < ApplicationController
def create
auth = request.env["omniauth.auth"]
user = User.find_by_provider_and_uid(auth["provider"], auth["uid"]) || User.create_with_omniauth(auth)
session[:user_id] = user.id
redirect_to root_url, :notice => "Signed in!"
end
def destroy
session[:user_id] = nil
redirect_to root_url, :notice => "Signed out!"
end
end
and the routes.rb is
Lovelinkedin::Application.routes.draw do
root :to => "users#index"
match "/auth/:provider/callback" => "sessions#create"
match "/auth/failure" => "users#index"
match "/signout" => "sessions#destroy", :as => :signout
end
and my omniauth.rb is
Rails.application.config.middleware.use OmniAuth::Builder do
provider :linkedin, 'xxxxx', 'ffffffff'
end
Please help me.
thanks in advance

What is your OmniAuth.config.full_host equal to in your omniauth.rb file?
if its redirecting to a secure site then it should be something like this:
"https://#{SITE_BASE}"
else just take off the s if its not a secure site

Related

Devise not binding session (Omniauth) in Rails 4

I use Omniauth with Devise in my rails app. I managed to get the user signed in correctly when they are using omniauth (in this case, facebook). When the user try to login by using their email and password instead of omniauth, the app will still logged the user in but it does not store the session. So, there is no sign out button being shown and the user cannot do the thing that he/she suppose to do.
This is my route for user :
devise_for :users, path_names: {sign_in: "login", sign_out: "logout"}, controllers: {registrations: 'registrations', omniauth_callbacks: "omniauth_callbacks"}, :skip => [:sessions]
as :user do
get 'sign-in' => 'devise/sessions#new', :as => :new_user_session
post 'sign-in' => 'devise/sessions#create', :as => :user_session
get '/users/sign_out' => 'devise/sessions#destroy'
resources :users_admin, :controller => 'users'
end
This is my OmniauthCallbacksController:
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def all
user = User.from_omniauth(request.env["omniauth.auth"])
if user.persisted?
session[:user_id] = user.id
sign_in_and_redirect user, notice: "Signed in!"
else
session["devise.user_attributes"] = user.attributes
redirect_to new_user_registration_url
end
end
alias_method :facebook, :all
end
This is my SessionController:
class SessionsController < ApplicationController
def create
user = User.from_omniauth(env["omniauth.auth"])
session[:user_id] = user.id
redirect_to root_url
end
def destroy
session[:user_id] = nil
redirect_to root_url
end
end
And the tutorial that I am following is here: https://www.youtube.com/watch?v=X6tKAUOMzCs
Please help..thanks!
The code of SessionsController is wrong. In create action you're trying to authenticate user from omniauth, but this controller is not used for OAuth authentication. This is why it doesn't save anything in session. Moreover, there's seem to be a typo: you use env["omniauth.auth"] instead of request.env["omniauth.auth"].
Actually, you don't need to modify SessionsController or create your own. Devise's default SessionsController works fine. You just need to turn on Omniauthable, connect omniauth-provider and that's all. Route settings would look like this:
devise_for :users, controllers: {omniauth_callbacks: 'omniauth_callbacks'}
You can find the code from the video in this repo: https://github.com/railscasts/235-devise-and-omniauth-revised/tree/master/blog-after Hopefully, it will help you.
For me, only add sign_in user after persiste solves. The sign_in user will add the user into the current_user and set the session.
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def all
user = User.from_omniauth(request.env["omniauth.auth"])
if user.persisted?
sign_in user
else
session["devise.user_attributes"] = user.attributes
redirect_to new_user_registration_url
end
end
end
end

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

Rails Omniauth Facebook login redirects to sign up

for some reason my Omniauth Facebook login is redirecting to /users/sign_up#= - but otherwise appears to be working. I have this in routes.rb:
devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks" }
I have this in application.html.erb:
<%= link_to "", user_omniauth_authorize_path(:facebook, :origin=>"root_url") %>
<%= link_to(image_tag("FB-Login.png"),
user_omniauth_authorize_path(:facebook), :origin=>"root_url", class:"mycss") %>
I have this in application_controller.rb:
def after_sign_in_path_for(resource_or_scope)
Rails.logger.level = 0
logger.debug "after_sign_in_path_for"
logger.debug "Session: #{#session.inspect}"
logger.debug "omniauth.origin: #{omniauth.origin}"
logger.debug "root_url: #{root_url}"
## if request.env['omniauth.origin']
## request.env['omniauth.origin']
request.env['omniauth.origin'] || root_url
end
Funny thing is the log statements are not showing in the heroku logs - looks like after_sign_in_path_for is not called ??
Any help appreciated,
Slavko
Maybe that user already exist?
Try to check user existence prior to persistence:
def facebook
#user = User.from_omniauth(request.env["omniauth.auth"])
if #user
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

Omniauth + Devise Redirect Error

I have the following problem: My app is running as a Facebook app, but on the first time that the user accept's it's Facebook permissions, it's redirected to the right URL, but outside the Facebook (canvas). How can I fix it?
Here is my actual settings:
devise.rb:config.omniauth :facebook, ENV['FACEBOOK_APP_ID'], ENV['FACEBOOK_SECRET'], scope: "email,publish_stream"
app/controllers/omniauth_callback_controller.rb
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def passthru
render :file => "#{Rails.root}/public/404.html", :status => 404, :layout => false
end
def facebook
#user = User.find_for_facebook_oauth(request.env["omniauth.auth"], current_user)
if #user.persisted?
flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Facebook"
sign_in_and_redirect #user, :event => :authentication
else
session["devise.facebook_data"] = request.env["omniauth.auth"]
redirect_to root_path
end
end
def after_sign_in_path_for(resource)
inicio_path
end
end
routes.rb
Pl::Application.routes.draw do
ActiveAdmin.routes(self)
mount Resque::Server, :at => "/resque"
devise_for :admin_users, ActiveAdmin::Devise.config
devise_for :users, :controllers => { :omniauth_callbacks => "omniauth_callbacks" }
devise_scope :user do
get '/users/auth/:provider' => 'users/omniauth_callbacks#passthru'
end
match 'states' => 'game_plays#states'
match 'cities' => 'game_plays#cities'
match 'parties' => 'game_plays#parties'
match 'prefeito' => 'game_plays#prefeito'
match 'prefeitos' => 'game_plays#prefeitos'
match 'vereadores' => 'game_plays#vereadores'
match 'parties' => 'game_plays#parties'
match 'qualities' => 'game_plays#qualities'
match 'start' => 'game_plays#start'
match 'generated_image' => 'game_plays#generated_image'
match 'save_game_play' => 'game_plays#save_game_play'
match 'final' => 'game_plays#final', :as => :final
match 'inicio' => 'game_plays#index'
root :to => 'game_plays#bem_vindo'
end
Any sugestions?
This is from my own experience a couple months ago with this issue and I hope it helps.
From Facebook's point of view, this is exactly what it is suppose to do. It does not recognize the difference between where the request is coming from. You have to change the redirect URL on the request for it to stay in the iframe.
The easiest way I found to do this was to have the iframe url go to my_website.com/fb-app, which sets a session variable to let you know you are in the canvas and ensures they are already logged in through facebook. It then redirects them to the canvas site where the site continues as normal and the user never notices anything.
def fbapp
session[:fbapp] = true
if user_signed_in? == false
redirect_to user_omniauth_authorize_path(:facebook)
else
redirect_to $APP_CANVAS_URL + "?auth_token=" + current_user.authentication_token
end
end
Then, in your Application_controller.rb you need to change the redirect path. This is what it looked like in my application, note $APP_CANVAS_URL should be something along the lines of https://apps.facebook.com/your_app_here
def after_sign_in_path_for(resource_or_scope)
if session[:fbapp] == true
$APP_CANVAS_URL + "?auth_token=" + current_user.authentication_token
else
root_path
end
end
I doubt this is the best way, but it's what I got to work for me after hours of frustration. I hope it helps.

Advanced contraints in rails 3 for user-centric routing

Learning rails development and would usually prefer to search out an answer than waste peoples time but this has been doing my head in all night.
Essentially I'm trying to present user-dependant views ala github etc.
I'm trying to follow the instructions laid out here:
http://collectiveidea.com/blog/archives/2011/05/31/user-centric-routing-in-rails-3/
My authentication at the moment is from the railscast "Authentication from Scratch - revised" which uses sessions, my sessions_crontroller.rb:
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by_email(params[:email])
if user && user.authenticate(params[:password])
session[:user_id] = user.id
redirect_to root_url, notice: "Logged in!"
else
flash.now.alert = "Email or password is invalid"
render "new"
end
end
def destroy
session[:user_id] = nil
redirect_to root_url, notice: "Logged out!"
end
end
And my routes.rb:
C::Application.routes.draw do
root :to => "static_pages#home", :constraints => LoggedInConstraint.new(false)
root :to => "users#show", :constraints => LoggedInConstraint.new(true)
resources :users
resources :sessions
As per my understanding, because I'm not using cookies the final comment under that blog posts recommends using request.session[:your_key] in place of request.cookies.key?("user_token") however when logged in I am still taken to static_pages#home? If anyone could shed some light on the topic I would very much appreciate it.
I also apologise for any formatting errors etc, this is my first question on stackoverflow.
Thanks again!
Not sure about your exact question, but I just did something kind of similar to this, so maybe my code will help you:
My routes:
# Except from config/routes.rb
require File.expand_path("../../lib/role_constraint", __FILE__)
MyApp::Application.routes.draw do
mount Resque::Server, :at => "/resque", :constraints => RoleConstraint.new('admin')
...
...
...
My constraint:
# lib/role_constraints.rb
class RoleConstraint < Struct.new(:value)
def matches?(request)
request.session[:role] == value
end
end
My sessions controller:
# app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
before_filter :require_user, :only => :destroy
def new
end
def create
user = User.find_by_username(params[:username])
if user && user.authenticate(params[:password])
session[:user_id] = user.id
# Just for /resque
# Not secure - if you change a user's role, it will not be updated here
# until they log out and log in again.
session[:role] = user.role
if user.email.nil?
redirect_to user, :notice => "Please add your email address to your account"
else
redirect_to root_url, :notice => "Logged in!"
end
else
flash.now.alert = "Invalid email or password"
render "new"
end
end
def destroy
session[:user_id] = nil
session[:current_project_id] = nil
redirect_to root_url, :notice => "Logged out!"
end
end

Resources