I am using rails HTTP digest authentication on some of my website's controller. It is working fine for my purpose but it timeout very quick.
How can I adjust the timeout parameter for HTTP digest authentication?
How can I implement logout for HTTP basic authentication?
Thanks,
If a user leaves the site, or closes their browser, etc, and you would like them to stay logged in:
In your SessionsController:
def create
member = Member.find_by_user_name(params[:user_name])
if member && member.authenticate(params[:password])
session[:member_id] = member.id
if params["remember_me"] == "1"
cookies[:digest] = {:value => member.password_digest, :expires => Time.now + 720000}
else
cookies[:digest] = nil
end
redirect_to (url_to_go_to_after_login), :notice => "Logged in!"
else
redirect_to (login_url), :alert => "Invalid email or password"
end
end
How to log out a user:
def destroy
session[:member_id] = nil
cookies[:digest] = nil
redirect_to url_to_go_to_after_logout, :notice => "Logged out!"
end
How to log in a user from the rememberme cookie:
def new
if member = Member.find_by_password_digest(cookies[:digest])
session[:member_id] = member.id
redirect_to (url_to_go_to_after_login), :notice => "Hello#{member.first_name}"
end
end
To set the expire time for later (should work in rails > 2.3 https://github.com/rails/rails/blob/2-3-stable/actionpack/lib/action_controller/session/abstract_store.rb#L175 ):
Your::Application.config.session_store :active_record_store, {
key: "your_session_id",
domain: ".your-domain.com",
expire_after: 48.hours,
}
Related
I am trying to deploy my rails application. I have a small requirement here.
I am not using Devise. I am providing user to login via his username and password. But now I also want to provide user to login via his email too.
How can I make this work. It should work for username and also for email.
My access controller login action is like this:
def attempt_login
if params[:username].present? && params[:password].present?
p 'Fields Check'
found_user = User.where(:username => params[:username]).first
p "#{#found_user.inspect}"
if found_user
authorized_user = found_user.authenticate(params[:password])
end
end
p "#{authorized_user.inspect}"
if authorized_user
if authorized_user.email_confirmed
# mark user as logged in
session[:user_id] = authorized_user.id
session[:username] = authorized_user.username
redirect_to(:controller => 'users',:action => 'index')
else
flash[:error] = 'Please activate your account by following the
instructions in the account confirmation email you received to proceed'
redirect_to(:controller => 'home',:action => 'index')
end
else
p "Not a Registered User"
flash[:error] = "Invalid username/password combination."
redirect_to(:controller => 'home',:action => 'index')
end
end
Thanks in advance :)
You just have to change the initial check as follows
if (params[:username].present? || params[:email].present?) && params[:password].present?
and then the query to find the user
User.where('username= ? OR email= ?', params[:username], params[:email]).first
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
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
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.
In my Rails app I'm trying to produce a separate flash.now[:alert] for invalid :email and :password, respectively. So if a user enters the correct email but wrong password, the :alert warns the user of an invalid password and vice versa. Here's what I have in my SessionsController:
def create
if user = User.authenticate(params[:email], params[:password])
session[:user_id] = user.id
redirect_to user.profile, :notice => "Logged in successfully"
elsif user.email != params[:email]
session[:email] = #user.email
flash.now[:alert] = "Invalid email. Try again!"
render :action => 'new'
else
session[:password] = #user.password
flash.now[:alert] = "Invalid password. Try again!"
render :action => 'new'
end
end
Rendering this gives me an undefined method for email. Can anyone help me figure out what I'm doing wrong?
DISCLAIMER: Obviously this is a really bad idea as an attacker could keep on trying emails until he found one that did match and then he could start trying passwords for this email he knows exists at your database, but you're asking, so it's up to you deciding to do this or not.
Your authenticate method obviously only returns the user if the email and password did match, change your authenticate method to return a boolean and a user if there is any available. It would look somewhat like this:
def authenticate(email, password)
u = first(:conditions => {:email => email, :state => 'active'})
u && u.authenticated?(password) ? [true, u] : [false, u]
end
Then, at your controller:
def create
result , user = User.authenticate(params[:email], params[:password])
if result
session[:user_id] = user.id
redirect_to user.profile, :notice => "Logged in successfully"
elsif user
session[:email] = #user.email
flash.now[:alert] = "Invalid email. Try again!"
render :action => 'new'
else
session[:password] = #user.password
flash.now[:alert] = "Invalid password. Try again!"
render :action => 'new'
end
end
And this should work.