Rails: Heroku with Omniauth and Facebook - ruby-on-rails

I am working on an app that allows you to authenticate with Facebook to signup and log into the app. For some reason when working with multiple dynos, it appears that session management isn't carried over.
I can watch my logs log the user in, but when the user is redirected, the app logs the user out for some reason
Here is my AuthorizationsController:
class AuthorizationsController < ApplicationController
skip_before_filter :redirect_to_signed_in_path, :prepare_for_mobile, :redirect_to_https, :force_www!
def create
authentication = Authorization.find_by_provider_and_uid(auth['provider'], auth['uid'])
if authentication
flash[:notice] = "Signed In Successfully"
sign_in authentication.user, event: :authentication
redirect_to root_path
elsif user_signed_in?
current_user.apply_omniauth(auth)
if current_user.save
current_user.update_attribute(:"allow_#{auth['provider']}_sync", true)
PullSocialActionsWorker.perform_async(current_user.id, auth["provider"])
redirect_to edit_social_profile_path, flash: { error: "#{auth["provider"]} Integration is processing" }
else
redirect_to edit_social_profile_path, flash: { error: "An error has occurred. Please try again." }
end
else
password = Devise.friendly_token[0,20]
athlete = Athlete.new(email: generate_auth_email(params[:provider]), password: password, password_confirmation: password )
athlete.apply_omniauth(auth)
begin
athlete.subscriptions.build(trial_expiry: DateTime.now + 30, active: true, account_type_id: AccountType.free.id)
if athlete.save(validate: false)
sign_in athlete, event: :authentication
redirect_to root_path, notice: "Account created and signed in successfully"
else
redirect_to root_path, flash: { error: "An error has occurred. Please try again." }
end
rescue ActiveRecord::RecordNotUnique
redirect_to root_path, flash: { error: "The email address you are trying to connect already exists. Perhaps you #{ActionController::Base.helpers.link_to "Forgot Your Password?", new_user_password_path}".html_safe }
end
end
end
def failure
redirect_to root_url, notice: "An Error has occurred. Please try again!"
end
private
def auth
request.env["omniauth.auth"]
end
def generate_auth_email(provider)
if provider == "twitter"
"#{auth.uid}#twitter.com"
else
auth.info.try(:email)
end
end
end
Gemfile:
gem 'omniauth'
gem 'omniauth-facebook', '1.4.0'
I am also using Memcache/Dalli for caching...
gem 'memcachier'
gem 'dalli'
Anyone else run into this issue before?

Related

session not working in post method in rails

session[:user_id] = user.id this session not working but its working in get method(login)
# Working fine here
# get 'users/login'=>'users#login'
def login
session[:user_id] = 1
end
# post 'users/auth'=>'users#loginpost'
def loginpost
user = User.authenticate(request.POST['name'], request.POST['password'])
if user
# But not working here:(
session[:user_id] = user.id
redirect_to root_url, :notice => "You are Successfully logged in ^^"
else
render html: '<strong>HTML String</strong>'
#render users_login_url, :notice => "You are entered invalid email or password"
end
end

Using same email adress to login Rails app through Oauth and Sorcery

I use Sorcery gem in my Rails app. Oauth authentication is working on Google and Github services. But if user has same emails to login to Google and Github, my application ignores other attempt to login, because the used email already stored in database.
So, I need multiple login in my app through Oauth, even if emails in different services is equal. What should I do?
You can do it like this:
put it in ./app/controller/oauths_controller.rb
def callback
provider = auth_params[:provider]
if #user = login_from(provider)
redirect_to root_path, :notice => "Logged in from #{provider.titleize}!"
else
begin
#user = create_from(provider)
reset_session # protect from session fixation attack
auto_login(#user)
redirect_to root_path, :notice => "Logged in from #{provider.titleize}!"
rescue
provider_hash = sorcery_fetch_user_hash(provider)
user_email = provider_hash[:user_info]['email']
#user = User.find_by_email(user_email)
#user.authentications.create!(:provider => provider, :uid => provider_hash[:uid])
reset_session
auto_login(#user)
redirect_to root_path, :notice => "Logged in from #{provider.titleize}!"
rescue
redirect_to root_path, :alert => "Failed to login from #{provider.titleize}!"
end
end
end

Rails - Generate email address when one doesn't exist with Omniauth integration

I am working with omniauth with Rails and trying to get twitter, facebook and google hooked up for authentication but keep running into this error:
PG::Error: ERROR: duplicate key value violates unique constraint "index_users_on_email"
DETAIL: Key (email)=() already exists.
Here is my Authentication Controller:
class AuthorizationsController < ApplicationController
def create
authentication = Authorization.find_by_provider_and_uid(auth['provider'], auth['uid'])
if authentication
flash[:notice] = "Signed In Successfully"
sign_in authentication.user, event: :authentication
redirect_to root_path
else
athlete = Athlete.new
athlete.apply_omniauth(auth)
debugger
if athlete.save(validate: false)
flash[:notice] = "Account created and signed in successfully"
sign_in athlete, event: :authentication
redirect_to finalize_profile_path
else
flash[:error] = "An error has occurred. Please try again."
redirect_to root_path
end
end
end
def failure
render json: params.to_json
end
private
def auth
request.env["omniauth.auth"]
end
def resource(user_type)
user_type.downcase.to_sym
end
end
I think what is happening is that when the Athlete is created it is creating one with a blank email address and the unique key is failing... how could I get around this? I think I know how to fix this for Google integration but since Twitter doesn't return an email, this issue will not resolve itself
This is how I was able to get it working:
class AuthorizationsController < ApplicationController
def create
authentication = Authorization.find_by_provider_and_uid(auth['provider'], auth['uid'])
if authentication
flash[:notice] = "Signed In Successfully"
sign_in authentication.user, event: :authentication
redirect_to root_path
else
athlete = Athlete.new(email: generate_auth_email(params[:provider]) )
athlete.apply_omniauth(auth)
debugger
if athlete.save(validate: false)
flash[:notice] = "Account created and signed in successfully"
sign_in athlete, event: :authentication
redirect_to finalize_profile_path
else
flash[:error] = "An error has occurred. Please try again."
redirect_to root_path
end
end
end
def failure
render json: params.to_json
end
private
def auth
request.env["omniauth.auth"]
end
def resource(user_type)
user_type.downcase.to_sym
end
def generate_auth_email(provider)
return auth.info.try(:email) unless provider == "twitter"
return "#{auth.uid}#twitter.com" if provider == "twitter"
end
end
I create an email using the twitter uid with twitter.com being the domain since twitter does not return an email address
Hope this helps someone in the future

Devise and Omniauth

I'm trying to integrate Devise with Omniauth and have some troubles with them both. The main problem is to bind Devise User model with Omniauth authentications. I want a simple way to associate my user, with external providers like facebook, twitter, g+ and so on.
One of the most annoying issues that arise with my application is:
If an user registered on my site with devise (I call it local user), that means, provided an email and a password, when user tries to login with twitter, the system asks for mail confirmation. If that mail already exists, then user have to provide another mail. I want instead that he can confirm with a password that it is actually his email. How to do that? How can I override that template?
This is my authentications controller:
class AuthenticationsController < ApplicationController
def index
#authentications = Authentication.all
end
def create
#authentication = Authentication.new(params[:authentication])
if #authentication.save
redirect_to authentications_url, :notice => "Successfully created authentication."
else
render :action => 'new'
end
end
def destroy
#authentication = Authentication.find(params[:id])
#authentication.destroy
redirect_to authentications_url, :notice => "Successfully destroyed authentication."
end
def twitter
omni = request.env["omniauth.auth"]
authentication = Authentication.find_by_provider_and_uid(omni['provider'], omni['uid'])
if authentication
flash[:notice] = "Logged in Successfully"
sign_in_and_redirect User.find(authentication.user_id)
elsif current_user
token = omni['credentials'].token
token_secret = omni['credentials'].secret
current_user.authentications.create!(:provider => omni['provider'], :uid => omni['uid'], :token => token, :token_secret => token_secret)
flash[:notice] = "Authentication successful."
sign_in_and_redirect current_user
else
user = User.new
user.apply_omniauth(omni)
if user.save
flash[:notice] = "Logged in."
sign_in_and_redirect User.find(user.id)
else
session[:omniauth] = omni.except('extra')
p session
redirect_to new_user_registration_path
end
end
end
end
I also have no idea where new_users_registration_path is.

Authlogic with OAuth and OpenID - DoubleRenderError

I have authlogic and openid working correctly, and am trying to integrate oauth for twitter authentication. I do not want both a register and sign on button, so I have followed this example: Implicit user creation with Authlogic and Authlogic OAuth plugin
I get the DoubleRenderError on initial registration and subsequent log in, but refreshing the page lets the action complete successfully.
My users_controller create:
def create
#user = User.new(params[:user])
#user.save do |result| # LINE A
if result
flash[:notice] = "Account registered!"
redirect_to account_url
else
unless #user.oauth_token.nil?
#user = User.find_by_oauth_token(#user.oauth_token)
unless #user.nil?
UserSession.create(#user)
flash.now[:message] = "Welcome back!"
redirect_to account_url
else
redirect_back_or_default root_path
end
else
redirect_back_or_default root_path
end
end
end
end
And my user_sessions_controller create:
def create
#user_session = UserSession.new(params[:user_session])
#user_session.save do |result|
if result
flash[:notice] = "Login successful!"
redirect_back_or_default account_url
else
render :action => :new
end
end
end
Is there a way to resolve this? Thanks
After repeated failures, the following appears to work for normal authlogic username/password, OAuth with Twitter, and OpenID for at least google and yahoo, which is all I was interested in
def create
#user = User.new(params[:user])
#user.save do |result| # LINE A
if result
flash[:notice] = "Account registered!"
redirect_to account_url and return
else
if #user.oauth_token
#user = User.find_by_oauth_token(#user.oauth_token)
UserSession.create(#user)
flash.now[:message] = "Welcome back!"
redirect_to account_url and return
else
flash[:notice] = "Something went awry. Perhaps the name or email is already in use."
redirect_to register_path and return
end
end
end
end
Additionally, i added 'and return' into the update block in my users controller after both success and failure redirects/renders

Resources