Skip to content

Instantly share code, notes, and snippets.

@mustmodify
Created November 20, 2014 15:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mustmodify/f825c721fb7163d25ca3 to your computer and use it in GitHub Desktop.
Save mustmodify/f825c721fb7163d25ca3 to your computer and use it in GitHub Desktop.
my config/initializers/warden.rb file with comments.
# config/initializers/warden.rb
Rails.application.config.middleware.use Warden::Manager do |manager|
manager.default_strategies :password, :perishable_token
manager.failure_app = lambda { |env|
# Just to be clear, I'm not actually sold on failure apps. The intent
# here is that if an authentication strategy fails and a failure app is
# defined, then it controls the flow. I now think this should be handled
# on the controller level... don't define a failure app, and have your
# controllers test to see whether there is a current_user. Because sometimes
# you're ok with no user, but you still want to know if there is one.
Rails.logger.warn "[AUTH] Failed to authenticate. Going to UserSession#challenge.";
UserSessionsController.action(:challenge).call(env) }
end
Warden::Manager.serialize_into_session do |user|
# although Rails encrypts session info, it might still be advisable
# to have an access token here instead of an id.
user.id
end
Warden::Manager.serialize_from_session do |id|
User.find_by_id(id)
end
Warden::Manager.after_set_user do |user, auth, opts|
# if you set the user manually, as you might when
# you login a newly-created user, update their login count
if( user.login_count.blank? )
user.update_attribute( :login_count, 1 )
end
end
Warden::Strategies.add(:password) do
def valid?
# determine whether or not to use this strategy. If you use
# it and fail, then your failure_app will run. But if valid?
# is false, failure_app does not run because this strategy
# does not apply.
credential_params['email'] && credential_params['password']
end
def authenticate!
email = credential_params['email']
passwd = credential_params['password']
Rails.logger.warn("[AUTH] Authenticating user #{email} via email and password")
user = User.find_by_email(email)
if user.blank?
Rails.logger.warn("[AUTH] No Such User")
fail "Invalid email or password"
elsif user.authenticate( passwd )
Rails.logger.warn("[AUTH] User #{user.email} authenticated with a password.")
user.login_count ||= 0
user.update_attribute( :login_count, user.login_count + 1 )
success! user
else
Rails.logger.warn("[AUTH] Bad Password")
fail "Invalid email or password"
end
end
def credential_params
p = params.blank? ? post_params : params
p['user_session'] || {}
end
def post_params
@post_params ||= get_post_params
end
def get_post_params
# In rack, params[] doesn't include POST params
# ... that comes from a Rails helper.
req = Rack::Request.new(env)
if( req.post? )
begin
body = req.body.read
req.body.rewind
JSON.parse( body )
rescue
{'parse_error' => body.inspect}
end
else
{}
end
end
end
Warden::Strategies.add(:perishable_token) do
def valid?
params['token']
end
def store?
false
end
def matching_user
User.find_by_perishable_token(params['token'])
end
def authenticate!
Rails.logger.warn("[AUTH] Authenticating user via token")
matching_user.tap do |user|
if( user )
Rails.logger.warn("[AUTH] User #{user.email} authenticated with a token.")
success! user
else
Rails.logger.warn("[AUTH] No Such User")
fail "Invalid token."
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment