Skip to content

Instantly share code, notes, and snippets.

@krongk
Last active February 13, 2017 06:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save krongk/b3a9ab3750df04d621a0 to your computer and use it in GitHub Desktop.
Save krongk/b3a9ab3750df04d621a0 to your computer and use it in GitHub Desktop.
Devise + Omniauth + Oauth2 +(豆瓣、QQ、微博)
=begin
参考教程:http://www.douban.com/note/411359006/
Gem Omniauth(https://github.com/intridea/omniauth)
Gem omniauth-oauth2 (https://github.com/intridea/omniauth-oauth2)
流程参考:https://ruby-china.org/topics/6464
Devise and OmniAuth (revised) (http://railscasts.com/episodes/235-devise-and-omniauth-revised)
=end
# Gem lists
gem 'devise'
gem 'omniauth'
gem 'omniauth-oauth2'
# add three strategies
C:\Sites\tm_wed\lib\omniauth\strategies\douban.rb (https://gist.github.com/krongk/21f3bbc7a38085883a2c)
C:\Sites\tm_wed\lib\omniauth\strategies\tqq.rb (https://gist.github.com/krongk/22bc15da7bd37ea9f7ad)
C:\Sites\tm_wed\lib\omniauth\strategies\weibo.rb (https://gist.github.com/krongk/aedf1566ad6a8ffdba9f)
#config devise
# C:\Sites\tm_wed\config\initializers\devise.rb:
require 'omniauth/strategies/tqq'
require 'omniauth/strategies/douban'
require 'omniauth/strategies/weibo'
...
config.omniauth :tqq, ENV['TQQ_KEY'], ENV['TQQ_SECURT']
config.omniauth :douban, ENV['DOUBAN_KEY'], ENV['DOUBAN_SECURT']
config.omniauth :weibo, ENV['WEIBO_KEY'], ENV['WEIBO_SECURT']
#config model
# C:\Sites\tm_wed\app\models\user.rb:
# changes log:
# . add :omniauthable
# . add helper methods
class User < ActiveRecord::Base
rolify
devise :database_authenticatable, :registerable, :omniauthable,
:recoverable, :rememberable, :trackable, :validatable
has_many :sites, -> { order("updated_at DESC") }, :dependent => :destroy
def self.from_omniauth(auth)
where(auth.slice(:provider, :uid)).first_or_create do |user|
user.provider = auth.provider
user.uid = auth.uid
user.name = auth.info.nickname
end
end
def self.new_with_session(params, session)
if session["devise.user_attributes"]
new(session["devise.user_attributes"], without_protection: true) do |user|
user.attributes = params
user.valid?
end
else
super
end
end
def password_required?
super && provider.blank?
end
def update_with_password(params, *options)
if encrypted_password.blank?
update_attributes(params, *options)
else
super
end
end
end
#rake migration
# edit uid from int to bigint
class AddOmniauthToUsers < ActiveRecord::Migration
def change
add_column :users, :provider, :string
add_column :users, :uid, :integer
end
end
#update routes
# 修改routes.rb, 主要是指明回调方法路径
devise_for :users, :controllers => {:registrations => "registrations", omniauth_callbacks: "omniauth_callbacks"}
#create callback controller
# C:\Sites\tm_wed\app\controllers\omniauth_callbacks_controller.rb:
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
#skip CSRF on create.
skip_before_filter :verify_authenticity_token
def all
user = User.from_omniauth(request.env["omniauth.auth"])
if user.persisted?
sign_in_and_redirect user, notice: '登录成功'
else
session["devise.user_attributes"] = user.attributes
redirect_to new_user_registration_url
end
end
alias_method :tqq, :all
alias_method :douban, :all
alias_method :weibo, :all
end
#config views
# C:\Sites\tm_wed\app\views\devise\registrations\new.html.erb:
<h3>注册账户</h3>
<%= simple_form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :role => 'form'}) do |f| %>
...
<% if f.object.password_required? %>
<div class="form-group col-md-6">
<%= f.label :password %>
<%= f.password_field :password, class: 'required form-control' %>
</div>
<div class="form-group col-md-6">
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation, class: 'required form-control' %>
</div>
<% end %>
<%= f.submit '提 交 注 册', :class => 'btn btn-meflat' %>
<% end %>
# C:\Sites\tm_wed\app\views\devise\registrations\edit.html.erb:
<h3>修改账户</h3>
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put, :role => 'form'}) do |f| %>
...
<% if f.object.encrypted_password.present? %>
<fieldset>
<div class="form-group">
<%= f.label :current_password %>
<%= f.password_field :current_password, class: 'form-control' %>
</div>
</fieldset>
<% end %>
<%= f.submit '修 改', :class => 'button right' %>
<% end %>
# C:\Sites\tm_wed\app\views\devise\sessions\new.html.erb:
<div>
<%= link_to "QQ账号登录", user_omniauth_authorize_path(:tqq) %> |
<%= link_to "豆瓣账号登录", user_omniauth_authorize_path(:douban) %> |
<%= link_to "微博账号登录", user_omniauth_authorize_path(:weibo) %>
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment