Skip to content

Instantly share code, notes, and snippets.

@jhjguxin
Created June 15, 2012 05:22
Show Gist options
  • Save jhjguxin/2934805 to your computer and use it in GitHub Desktop.
Save jhjguxin/2934805 to your computer and use it in GitHub Desktop.
sina and tqq(open.t.qq.com) oauth2 base on bbtang relation gist is gist: 3865157
#relation gist is gist: 3865157
#git://gist.github.com/3865157.git
SinaConfig = YAML.load_file(Rails.root.join("config/oauth/sina.yml"))[Rails.env].symbolize_keys
Weibo2::Config.api_key = SinaConfig[:key]
Weibo2::Config.api_secret = SinaConfig[:secret]
Weibo2::Config.redirect_uri = SinaConfig[:callback]
TqqConfig = YAML.load_file(Rails.root.join("config/oauth/qq.yml"))[Rails.env].symbolize_keys
Tqq2::Config.api_key = TqqConfig[:app_key]
Tqq2::Config.api_secret = TqqConfig[:app_secret]
Tqq2::Config.redirect_uri = TqqConfig[:redirect_uri]
# encoding: UTF-8
class Users::CqqsyncsController < ApplicationController
skip_before_filter :verify_authenticity_token
skip_before_filter :authenticate_user!
def new
#client = OauthChina::Sina.new
#authorize_url = client.authorize_url
#Rails.cache.write(build_oauth_token_key(client.name, client.oauth_token), client.dump)
#redirect_to authorize_url
client = ConnectQQ::Client.new
#Rails.cache.write(client.secret, client)
#debugger
#通过设置state参数来区分注册({state: 'regirst'} or nil)还是绑定({state: 'bound'})
if params[:state].present?
redirect_to client.auth_code.authorize_url << "&" << {state: params[:state]}.to_param
else
redirect_to client.auth_code.authorize_url
end
end
#def oauth_create
def callback
#client = OauthChina::Sina.load(Rails.cache.read(build_oauth_token_key(params[:type], params[:oauth_token])))
#client.authorize(:oauth_verifier => params[:oauth_verifier])
#userinfo = client.access_token.get("http://api.t.sina.com.cn/account/verify_credentials.json").body
#userinfo = JSON.parse userinfo
#results = client.dump
set_seo_meta( title = "qq用户_设置本站帐号", meta_keywords= "qq用户,设置本站帐号,bbtang.com", meta_description = 'qq用户,设置本站帐号,bbtang.com')
begin
client = ConnectQQ::Client.from_code(params[:code])
#access_token = client.auth_code.get_token(params["code"])
#response = client.account.get_openid
#puts response
#request_params = {"oauth_consumer_key" => ConnectQQ::Config.api_key, "access_token" => client.token.token, "openid" => params["openid"], "oauth_version" => "2.a", "scope" => "all"}
#{"client_id"=>"100300526", "openid"=>"1DE327433AC84358E5B285C63E4CE73B"}
openid = JSON.parse client.account.get_openid.body.gsub("callback( ","").gsub(" );\n","")
response_parsed = client.users.info(openid) if openid.present?
userinfo = JSON.parse response_parsed.body
userinfo = convert_profile(userinfo) if userinfo.present?
rescue => err
puts err
puts "now redirect_to #{users_tqq_sync_new_path}"
redirect_to users_cqq_sync_new_path
else
puts "now check client and save user .."
if client.is_authorized?
authorization = { uid: openid["openid"],
provider: params[:type],
access_token: client.token.token,
access_token_secret: client.secret
}
if params[:state].eql? "bound"
if user_signed_in?
if oauth_bound(user = current_user,authorization = authorization).present?
flash[:notice] = I18n.t("omniauth.bound", oauth: I18n.t("#{authorization[:provider]}"))
else
flash[:notice] = I18n.t("omniauth.cannot_bound", oauth: I18n.t("#{authorization[:provider]}"))
end
redirect_to share_info_profiles_path
else
flash[:notice] = I18n.t("omniauth.bound_without_sign_in", oauth: I18n.t("#{authorization[:provider]}"))
redirect_to new_user_session_path
end
else
oauth_signup_and_redirect(authorization = authorization, userinfo = userinfo)
end
else
flash[:notice] = "授权失败!"
redirect_to root_path
end
ensure #这里的代码在总是被执行,可以做一些清理工作
puts "sync process finished ..."
end
end
private
def build_oauth_token_key(name, oauth_token)
[name, oauth_token].join("_")
end
def convert_profile(profile={})
if profile.present?
mappings = {"figureurl_2" => "profile_image_url", "nickname" => "name"}
keys = ["figureurl_2","nickname","gender"]
p = profile.select{|k,v| keys.include? k}
p["gender"] = set_gender p["gender"]
#profile.select{|k,v| mappings.keys.include? k}
p.keys.each do |k|
if mappings.keys.include? k
p[mappings[k]] = profile[k]
p.delete(k)
end
end
return p.merge({"city" => ""})
else
{}
end
end
def set_gender(sex = "")
sex = sex.to_s
if ["男","女"].include? sex.to_s
(sex.eql? "女") ? true : false
end
end
def handle_unverified_request
true
end
def oauth_signup_and_redirect(authorization = {}, userinfo = {})
access_hash = authorization.select{|k,_| [:access_token, :access_token_secret].include? k}
session[:access_hash] = access_hash
session[:omniauth] = authorization[:provider]
session[:uid] = authorization[:uid]
session[:login] = "email"
session[:profileinfo] = userinfo
auth_hash = {provider: session[:omniauth],uid: session[:uid]}
if @user = User.authorization(auth_hash).first and @user.present?
#@user.confirmation_token=nil
#@user.confirmed_at=Time.now if @user.confirmed_at.nil?
authorization = Authorization.where(auth_hash).first
if authorization.present? and access_hash.present?
puts "try update access_token and access_token_secret ..."
authorization.update_attributes(access_hash)
end
@user.skip_confirmation!
@user.save
sign_in(:user,@user)
flash[:notice]=I18n.t("devise.sessions.user.signed_in")
#profile.save
session[:access_hash] = nil
session[:omniauth]=nil
session[:uid]=nil
session[:login]=nil
session[:profileinfo]=nil
redirect_to after_sign_in_path_for(@user)
else
redirect_to new_users_omniauth_emails_path
end
end
#oauth_bound(current_user,{uid: "123414", provider: "sina", access_token: "12341414", access_token_secret: "dfasdfaf"})
def oauth_bound(user,authorization = {})
require_keys = [:uid, :provider, :access_token, :access_token_secret]
if user.present? and !(require_keys.collect{|k| authorization.has_key? k or authorization.has_key? k.to_s}.include? false) and User.authorization(authorization.select{|k,_| [:uid, :provider].include? k}).empty?
user.authorizations.create(authorization)
end
end
end
gem "weibo2", "~> 0.1.0"
gem "tqq2", :git => "git://github.com/jhjguxin/tqq2.git"
gem "connect-qq", :git => "git://github.com/jhjguxin/connect-qq.git"
#coding: utf-8
class Users::OmniauthEmailsController < ApplicationController
def new
if session[:omniauth].present? and session[:uid].present? and session[:login].present?
@auth_email = true
set_seo_meta(title="开放平台用户_设置本站帐号",meta_keywords="开放平台用户,设置本站帐号,bbtang.com",meta_description = '开放平台用户,设置本站帐号,bbtang.com')
render :template => "site/map"
else
flash[:notice] = "设置本站帐号,授权失败!"
redirect_to root_path
end
end
def auth_email
#if validate_email(params[:email]) and validate_username(params[:username])
if session[:uid].present? and session[:omniauth].present? and validate_email(params[:email]) and params[:email].present?
#if false
@user=User.new(:email => params[:email], :password => Devise.friendly_token[0,20])
#@user.omniauth_type=session[:omniauth]
#@user.uid= session[:uid]
#@user.confirmation_token=nil
#@user.confirmed_at=Time.now
@user.skip_confirmation!
authorization_hash = {provider: session[:omniauth], uid: session[:uid]}
authorization_hash.merge!(session[:access_hash]) if session[:access_hash].present?
if @user.create_oauth_user(authorization_hash)
#breakpoint
#@user=User.create(:email => params[:email], :password => params[:password])
#@user.omniauth_type=session[:omniauth]
#@user.uid=session[:uid]
#@user.confirmation_token=nil
#@user.confirmed_at=Time.now
#@user.skip_confirmation!
#@user.save
profile=Profile.find_or_create_by_user_id(:user_id=>@user.id)
#breakpoint
profile.update_attributes(:nickname=>session[:profileinfo]["name"],:gender=> session[:profileinfo]["gender"],:city=> session[:profileinfo]["city"], :oauth_face_image_url => session[:profileinfo]["profile_image_url"])
session[:access_hash] = nil
session[:omniauth] = nil
session[:uid] = nil
session[:login] = nil
session[:profileinfo] = nil
flash[:notice] = I18n.t("login_successed")
sign_in(:user,@user)
redirect_to after_sign_in_path_for(@user)
#redirect_to new_profile_path(is_commend?: true )
#profile.save
else
@questions = recommend_questions_by_position("front_page_questions")
@cnt_answered = count_question_answered
@cnt_toanswer = count_question_toanswer
@experts = recommend_users_by_position("front_page_experts")
@auth_email = true
render :template => "site/map"
end
else
#render :new
@questions = recommend_questions_by_position("front_page_questions")
@cnt_answered = count_question_answered
@cnt_toanswer = count_question_toanswer
@experts = recommend_users_by_position("front_page_experts")
@auth_email = true
render :template => "site/map"
end
end
def destroy
provider = params[:provider]
if user_signed_in? and provider.present?
if current_user.respond_to? provider
auth = current_user.send(provider)
auth.destroy if auth.present?
flash[:notice] = I18n.t("omniauth.unbound", oauth: I18n.t("#{provider}"))
end
end
respond_to do |format|
format.html { redirect_to :back }
format.json { head :no_content }
end
end
def validate_email(email)
reg=/^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
if not reg.match(email)
flash[:alert]=I18n.t("activerecord.errors.models.user.attributes.email.invalid")
return false
end
return true
end
#检测用户名
def validate_username(username)
return true
end
end
#encoding: utf-8
#应用名称:棒棒糖母婴社区
#应用类型:站内应用—非托管
#接口权限:初级权限 查看接口权限详细说明
#来源显示:未生效来源显示详细说明
#测试应用地址:http://app.t.qq.com/app/playtest/801169142"
development:
app_name: "站内应用—非托管"
app_type: "棒棒糖母婴社区"
app_key: "xxxxxxxxxx"
app_secret: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
redirect_uri: "http://www.bbtang.com:3000/users/tqqsyncs/tqq/callback"
app_permit: "初级权限 查看接口权限详细说明"
app_test_address: "http://app.t.qq.com/app/playtest/801169142"
production:
app_name: "站内应用—非托管"
app_type: "棒棒糖母婴社区"
app_Key: "xxxxxxxxxxxxxxxxxxxx"
app_secret: "xxxxxxxxxxxxxxxxxxxxxxxx"
redirect_uri: "http://www.bbtang.com/users/tqqsyncs/tqq/callback"
app_permit: "初级权限 查看接口权限详细说明"
app_test_address: "http://app.t.qq.com/app/playtest/801169142"
test:
app_name: "站内应用—非托管"
app_type: "棒棒糖母婴社区"
app_Key: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
app_secret: "xxxxxxxxxxxxxxxxxxxxxx"
redirect_uri: "http://www.bbtang.com:3000/users/tqqsyncs/tqq/callback"
app_permit: "初级权限 查看接口权限详细说明"
app_test_address: "http://app.t.qq.com/app/playtest/801169142"
match "sinasyncs/:type/new" => "sinasyncs#new", :as => :sina_sync_new, :type => "sina" #":type"'s mean is 'client.name' eg. "sina"
match "sinasyncs/:type/callback" => "sinasyncs#callback", :as => :sina_sync_callback, :type => "sina"
match "tqqsyncs/:type/new" => "tqqsyncs#new", :as => :tqq_sync_new, :type => "tqq" #":type"'s mean is 'client.name' eg. "sina"
match "tqqsyncs/:type/callback" => "tqqsyncs#callback", :as => :tqq_sync_callback, :type => "tqq"
development:
key: "4075568915"
secret: "16381b9956c0fe891cf7c40a12d80bac"
url: "http://www.bbtang.com:3000"
callback: "http://www.bbtang.com:3000/users/sinasyncs/sina/callback"
with_offical_account: "1"
production:
key: "4075568915"
secret: "16381b9956c0fe891cf7c40a12d80bac"
url: "http://www.bbtang.com/"
callback: "http://www.bbtang.com/users/sinasyncs/sina/callback"
with_offical_account: "1"
test:
key: "4075568915"
secret: "16381b9956c0fe891cf7c40a12d80bac"
url: "http://www.bbtang.com:3000"
callback: "http://www.bbtang.com:3000/users/sinasyncs/sina/callback"
with_offical_account: "1"
# encoding: UTF-8
class Users::SinasyncsController < ApplicationController
skip_before_filter :verify_authenticity_token
skip_before_filter :authenticate_user!, only: [:new, :callback]
def new
#client = OauthChina::Sina.new
#authorize_url = client.authorize_url
#Rails.cache.write(build_oauth_token_key(client.name, client.oauth_token), client.dump)
#redirect_to authorize_url
client = Weibo2::Client.new
#Rails.cache.write(client.secret, client)
#通过设置state参数来区分注册({state: 'regirst'} or nil)还是绑定({state: 'bound'})
if params[:state].present?
redirect_to client.auth_code.authorize_url << "&" << {state: params[:state]}.to_param
else
redirect_to client.auth_code.authorize_url
end
end
#def oauth_create
def callback
#client = OauthChina::Sina.load(Rails.cache.read(build_oauth_token_key(params[:type], params[:oauth_token])))
#client.authorize(:oauth_verifier => params[:oauth_verifier])
#userinfo = client.access_token.get("http://api.t.sina.com.cn/account/verify_credentials.json").body
#userinfo = JSON.parse userinfo
#results = client.dump
set_seo_meta(title="新浪微博用户_设置本站帐号",meta_keywords="新浪微博用户,设置本站帐号,bbtang.com",meta_description = '新浪微博用户,设置本站帐号,bbtang.com')
begin
client = Weibo2::Client.from_code(params[:code])
response = client.account.get_uid
response_parsed = client.users.show(response.parsed) if response
userinfo = JSON.parse response_parsed.body
userinfo = convert_profile(userinfo)
rescue => err
puts err
puts "now redirect_to #{users_sina_sync_new_path}"
redirect_to users_sina_sync_new_path
else
puts "now check client and save user .."
if client.is_authorized?
authorization = { uid: response.parsed["uid"],
provider: params[:type],
access_token: client.token.token,
access_token_secret: client.secret
}
if params[:state].eql? "bound"
if user_signed_in?
if oauth_bound(user = current_user,authorization = authorization).present?
flash[:notice] = I18n.t("omniauth.bound", oauth: I18n.t("#{authorization[:provider]}"))
else
flash[:notice] = I18n.t("omniauth.cannot_bound", oauth: I18n.t("#{authorization[:provider]}"))
end
redirect_to share_info_profiles_path
else
flash[:notice] = I18n.t("omniauth.bound_without_sign_in", oauth: I18n.t("#{authorization[:provider]}"))
redirect_to new_user_session_path
end
else
oauth_signup_and_redirect(authorization = authorization, userinfo = userinfo)
end
else
flash[:notice] = "授权失败!"
redirect_to root_path
end
ensure #这里的代码在总是被执行,可以做一些清理工作
puts "sync process finished ..."
end
end
private
def build_oauth_token_key(name, oauth_token)
[name, oauth_token].join("_")
end
def convert_profile(profile={})
if profile.present?
profile["gender"] = (profile["gender"] == "f") ? true : false
profile["city"] = FindCity.new.getcity(profile["province"],profile["city"]).gsub("市","")
profile
else
{}
end
end
def handle_unverified_request
true
end
def oauth_signup_and_redirect(authorization = {}, userinfo = {})
access_hash = authorization.select{|k,_| [:access_token, :access_token_secret].include? k}
session[:access_hash] = access_hash
session[:omniauth] = authorization[:provider]
session[:uid] = authorization[:uid]
session[:login] = "email"
session[:profileinfo] = userinfo
auth_hash = {provider: session[:omniauth],uid: session[:uid]}
if @user = User.authorization(auth_hash).first and @user.present?
#@user.confirmation_token=nil
#@user.confirmed_at=Time.now if @user.confirmed_at.nil?
authorization = Authorization.where(auth_hash).first
if authorization.present? and access_hash.present?
puts "try update access_token and access_token_secret ..."
authorization.update_attributes(access_hash)
end
@user.skip_confirmation!
@user.save
sign_in(:user,@user)
flash[:notice]=I18n.t("devise.sessions.user.signed_in")
#profile.save
session[:access_hash] = nil
session[:omniauth]=nil
session[:uid]=nil
session[:login]=nil
session[:profileinfo]=nil
redirect_to after_sign_in_path_for(@user)
else
redirect_to new_users_omniauth_emails_path
end
end
#oauth_bound(current_user,{uid: "123414", provider: "sina", access_token: "12341414", access_token_secret: "dfasdfaf"})
def oauth_bound(user,authorization = {})
require_keys = [:uid, :provider, :access_token, :access_token_secret]
if user.present? and !(require_keys.collect{|k| authorization.has_key? k or authorization.has_key? k.to_s}.include? false) and User.authorization(authorization.select{|k,_| [:uid, :provider].include? k}).empty?
oauth = user.authorizations.new(authorization)
oauth.save
end
end
#def callback
#client = OauthChina::Sina.load(Rails.cache.read(build_oauth_token_key(params[:type], params[:oauth_token])))
#client.authorize(:oauth_verifier => params[:oauth_verifier])
#results = client.dump
#if results[:access_token] && results[:access_token_secret]
#在这里把access token and access token secret存到db
#下次使用的时候:
#breakpoint
#client = OauthChina::Sina.load(:access_token => "xx", :access_token_secret => "xxx")
#client.add_status("同步到新浪微薄..")
# flash[:notice] = "授权成功!"
#else
# flash[:notice] = "授权失败!"
#end
#redirect_to root_path
#end
end
# encoding: UTF-8
class Users::TqqsyncsController < ApplicationController
skip_before_filter :verify_authenticity_token
skip_before_filter :authenticate_user!
def new
#client = OauthChina::Sina.new
#authorize_url = client.authorize_url
#Rails.cache.write(build_oauth_token_key(client.name, client.oauth_token), client.dump)
#redirect_to authorize_url
client = Tqq2::Client.new
#Rails.cache.write(client.secret, client)
#debugger
=begin
#tqq 不支持 state 回传参数
if params[:state].present?
redirect_to client.auth_code.authorize_url << "&" << {state: params[:state]}.to_param
else
redirect_to client.auth_code.authorize_url
end
=end
redirect_to client.auth_code.authorize_url
end
#def oauth_create
def callback
#client = OauthChina::Sina.load(Rails.cache.read(build_oauth_token_key(params[:type], params[:oauth_token])))
#client.authorize(:oauth_verifier => params[:oauth_verifier])
#userinfo = client.access_token.get("http://api.t.sina.com.cn/account/verify_credentials.json").body
#userinfo = JSON.parse userinfo
#results = client.dump
set_seo_meta(title="腾讯微博用户_设置本站帐号",meta_keywords="腾讯微博用户,设置本站帐号,bbtang.com",meta_description = '腾讯微博用户,设置本站帐号,bbtang.com')
begin
client = Tqq2::Client.from_code(params[:code])
#access_token = client.auth_code.get_token(params["code"])
#response = client.account.get_openid
#request_params = {"oauth_consumer_key" => Tqq2::Config.api_key, "access_token" => client.token.token, "openid" => params["openid"], "oauth_version" => "2.a", "scope" => "all"}
response_parsed = client.users.info("openid" => params["openid"]) if params["openid"].present?
userinfo = JSON.parse response_parsed.body
userinfo = convert_profile(userinfo) if userinfo.present?
rescue => err
puts err
puts "now redirect_to #{users_tqq_sync_new_path}"
redirect_to users_tqq_sync_new_path
else
puts "now check client and save user .."
if client.is_authorized?
authorization = { uid: params[:openid],
provider: params[:type],
access_token: client.token.token,
access_token_secret: client.secret
}
if user_signed_in?
if oauth_bound(user = current_user,authorization = authorization).present?
flash[:notice] = I18n.t("omniauth.bound", oauth: I18n.t("#{authorization[:provider]}"))
else
flash[:notice] = I18n.t("omniauth.cannot_bound", oauth: I18n.t("#{authorization[:provider]}"))
end
redirect_to share_info_profiles_path
else
oauth_signup_and_redirect(authorization = authorization, userinfo = userinfo)
end
else
flash[:notice] = "授权失败!"
redirect_to root_path
end
ensure #这里的代码在总是被执行,可以做一些清理工作
puts "sync process finished ..."
end
end
private
def build_oauth_token_key(name, oauth_token)
[name, oauth_token].join("_")
end
def convert_profile(profile={})
if profile.present? and profile.has_key? "data"
profile = profile["data"]
mappings = {"location" => "city", "head" => "profile_image_url", "nick" => "name", "sex" => "gender"}
#profile.select{|k,v| mappings.keys.include? k}
profile.keys.each do |k|
if mappings.keys.include? k
profile[mappings[k]] = profile[k]
profile.delete(k)
end
end
profile["city"]=profile["city"].split(" ").last.gsub("市","")
profile["gender"] = set_gender profile["gender"]
gravatar = profile["profile_image_url"].to_s
profile["profile_image_url"] += (gravatar.end_with? '/') ? '' : '/'
profile["profile_image_url"] += (gravatar.end_with? '180') ? '' : '180'
profile
else
{}
end
end
def set_gender(sex = 0)
sex = sex.to_i
if [1,2].include? sex.to_i
sex==2 ? true : false
end
end
def handle_unverified_request
true
end
def oauth_signup_and_redirect(authorization = {}, userinfo = {})
access_hash = authorization.select{|k,_| [:access_token, :access_token_secret].include? k}
session[:access_hash] = access_hash
session[:omniauth] = authorization[:provider]
session[:uid] = authorization[:uid]
session[:login] = "email"
session[:profileinfo] = userinfo
auth_hash = {provider: session[:omniauth],uid: session[:uid]}
if @user = User.authorization(auth_hash).first and @user.present?
#@user.confirmation_token=nil
#@user.confirmed_at=Time.now if @user.confirmed_at.nil?
authorization = Authorization.where(auth_hash).first
if authorization.present? and access_hash.present?
puts "try update access_token and access_token_secret ..."
authorization.update_attributes(access_hash)
end
@user.skip_confirmation!
@user.save
sign_in(:user,@user)
flash[:notice]=I18n.t("devise.sessions.user.signed_in")
#profile.save
session[:access_hash] = nil
session[:omniauth]=nil
session[:uid]=nil
session[:login]=nil
session[:profileinfo]=nil
redirect_to after_sign_in_path_for(@user)
else
redirect_to new_users_omniauth_emails_path
end
end
#oauth_bound(current_user,{uid: "123414", provider: "sina", access_token: "12341414", access_token_secret: "dfasdfaf"})
def oauth_bound(user,authorization = {})
require_keys = [:uid, :provider, :access_token, :access_token_secret]
if user.present? and !(require_keys.collect{|k| authorization.has_key? k or authorization.has_key? k.to_s}.include? false) and User.authorization(authorization.select{|k,_| [:uid, :provider].include? k}).empty?
oauth = user.authorizations.new(authorization)
oauth.save
end
end
end
Weibo2::Strategy::AuthCode.class_eval do
# The Authorization Code Strategy
# setting on yml
# with_offical_account: "1"
# @see http://tools.ietf.org/html/draft-ietf-oauth-v2-15#section-4.1
def authorize_url(params={})
params = {:redirect_uri => @client.redirect_uri}.merge(params)
params = params.merge({"with_offical_account" => with_offical_account}) if with_offical_account?
super params
end
private
def with_offical_account
Askjane::Config.sina[:with_offical_account] if Askjane::Config.sina[:with_offical_account].present?
end
def with_offical_account?
true if Askjane::Config.sina[:with_offical_account].eql? "1"
end
end
#client = Weibo2::Client.new
#client.auth_code.authorize_url
#client.auth_code.hello
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment