Skip to content

Instantly share code, notes, and snippets.

@jnunemaker
Created November 8, 2009 01:11
Show Gist options
  • Save jnunemaker/229007 to your computer and use it in GitHub Desktop.
Save jnunemaker/229007 to your computer and use it in GitHub Desktop.
simple auth using twitter gem and sign in with twitter
class ApplicationController < ActionController::Base
include TwitterAuth::Helpers
helper :all
protect_from_forgery
rescue_from Twitter::Unauthorized, :with => :force_sign_in
private
def force_sign_in(exception)
reset_session
flash[:error] = 'Seems your credentials are not good anymore. Please sign in again.'
redirect_to new_session_path
end
end
# lib/twitter_auth
module TwitterAuth
module Helpers
def self.included(controller)
controller.send :include, InstanceMethods
controller.class_eval do
helper_method :current_user
helper_method :signed_in?
hide_action :current_user, :signed_in?
end
end
module InstanceMethods
def current_user
@_current_user ||= user_from_session
end
def signed_in?
!current_user.nil?
end
protected
def authenticate
deny_access unless signed_in?
end
def user_from_session
if session[:user_id].present?
User.find_by_id(session[:user_id])
end
end
def sign_in(user)
if user
session[:user_id] = user.id
end
end
def redirect_back_or(default)
session[:return_to] ||= params[:return_to]
if session[:return_to]
redirect_to(session[:return_to])
else
redirect_to(default)
end
session[:return_to] = nil
end
def redirect_to_root
redirect_to root_url
end
def store_location
session[:return_to] = request.request_uri if request.get?
end
def deny_access(flash_message = nil, opts = {})
store_location
flash[:failure] = flash_message if flash_message
render :template => "/sessions/new", :status => :unauthorized
end
end
end
end
<div id="login">
<%- form_tag session_path do -%>
<%= image_submit_tag 'twitter_sign_in.png' %>
<%- end -%>
</div>
class SessionsController < ApplicationController
def new
end
def create
oauth.set_callback_url(finalize_session_url)
session[:request_token] = oauth.request_token.token
session[:request_secret] = oauth.request_token.secret
redirect_to oauth.request_token.authorize_url
end
def destroy
reset_session
redirect_to new_session_path
end
def finalize
oauth.authorize_from_request(session[:request_token], session[:request_secret], params[:oauth_verifier])
session[:request_token] = session[:request_secret] = nil
profile = Twitter::Base.new(oauth).verify_credentials
user = User.find_or_create_by_screen_name(profile.screen_name.downcase)
user.update_attributes({
:atoken => oauth.access_token.token,
:asecret => oauth.access_token.secret,
})
session[:access_token] = oauth.access_token.token
session[:access_secret] = oauth.access_token.secret
sign_in(user)
redirect_back_or root_path
end
private
def oauth
@oauth ||= Twitter::OAuth.new(ENV['TEXTUAL_TOKEN'], ENV['TEXTUAL_SECRET'], :sign_in => true)
end
end
class User
include MongoMapper::Document
key :screen_name, String
key :email, String
key :atoken, String
key :asecret, String
timestamps!
validates_uniqueness_of :screen_name
validates_uniqueness_of :email
# make sure email is downcase
def email=(value)
value = value.present? ? value.downcase : nil
super(value.downcase)
end
# make sure screen name is downcase
def screen_name(value)
value = value.present? ? value.downcase : nil
super(value.downcase)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment