rails oauth第三方登陆

使用gem ‘devise’、’omniauth’、’omniauth-oauth2’ , 来实现Omniauth第三方登陆

1.在gemfile文件里添加gem,之后bundle

gem 'omniauth'
gem 'omniauth-oauth2'

2.在lib/omniauth/strategies/下新增基本的配置文件,已qq_connect为例,代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
require 'omniauth/strategies/oauth2'
module OmniAuth
module Strategies
class QQConnect < OmniAuth::Strategies::OAuth2
option :name, "qq_connect"
option :client_options, {
:site => 'https://graph.qq.com/oauth2.0/',
:authorize_url => '/oauth2.0/authorize',
:token_url => "/oauth2.0/token",
:token_formatter => lambda {|hash|
hash[:expires_in] = hash['expires_in'].to_i
hash.delete('expires_in')
}
}
option :token_params, {
:state => 'foobar',
:parse => :query
}
uid do
@uid ||= begin
access_token.options[:mode] = :query
access_token.options[:param_name] = :access_token
# Response Example: "callback( {\"client_id\":\"11111\",\"openid\":\"000000FFFF\"} );\n"
response = access_token.get('/oauth2.0/me')
#TODO handle error case
matched = response.body.match(/"openid":"(?<openid>\w+)"/)
matched[:openid]
end
end
info do
{
:nickname => raw_info['nickname'],
:name => raw_info['nickname'],
:image => raw_info['figureurl_1'],
}
end
extra do
{
:raw_info => raw_info
}
end
def raw_info
@raw_info ||= begin
#TODO handle error case
#TODO make info request url configurable
client.request(:get, "https://graph.qq.com/user/get_user_info", :params => {
:format => :json,
:openid => uid,
:oauth_consumer_key => options[:client_id],
:access_token => access_token.token
}, :parse => :json).parsed
end
end
end
end
end
OmniAuth.config.add_camelization('qq_connect', 'QQConnect')

3.集成devise,在/initializers/devise.rb,添加

require 'omniauth/strategies/qq_connect'
config.omniauth :QQConnect, 'key', 'a0dbf447esecurt381f8'

修改user.rb,添加 :omniauthable

devise :database_authenticatable, :registerable, :omniauthable

为user表添加列

rails g migration add_column_to_users provider uid
rake db:migrate

4.回调

创建controller,app/controllers/omniauth_callbaks_controller.rb,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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: 'success'
else
session["devise.user_attributes"] = user.attributes
redirect_to new_user_registration_url
end
end
alias_method :qq_connect, :all
end

修改user.rb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
devise :database_authenticatable, :registerable, :omniauthable,
:recoverable, :rememberable, :trackable, :validatable, :omniauth_providers => [:qq_connect]
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

5.修改路由

1
devise_for :users, :controllers => {:registrations => "registrations", omniauth_callbacks: "omniauth_callbacks"}

6.修改登陆view

<%= link_to "QQ账号登录",  user_omniauth_authorize_path(:tqq) %>

7.调试

去各大平台申请接入,修改本地hosts 添加
127.0.0.1 www.ceshi.com
回调地址填写完整例如:http://www.ceshi.cn/users/auth/qq_connect/callback
并且让本地rails服务跑在80端口
rails s -p 80

参考链接

http://www.douban.com/note/411359006/