使用qq登录

20 Aug 2013, by

QQ互联文档

基本步骤

基本代码如下:

# 设置路由
resources :users do
  collection do
    get 'qqlogin'
  end
end

# 控制器中跳转到登录验证的url
def qqlogin
    redirect_to Qq.redo("get_user_info")
end

# QQ登录类
#encoding=utf-8
#以下不需要改动
AUTHURL='https://graph.qq.com/oauth2.0/authorize?'
TOKENURL='https://graph.qq.com/oauth2.0/token?'
OPENIDURL='https://graph.qq.com/oauth2.0/me?access_token='
GETUSERINFOURL='https://graph.qq.com/user/get_user_info?'

require 'rubygems'
require 'net/http'
require 'uri'
require 'open-uri'
require 'rest-client'
require 'multi_json'

class Qq
	APPID = 'ID'
	APPKEY = 'KEY'
	REDURL = '&redirect_uri=uri'

	# 需要在本类中的其他方法中调用设置成实例变量
	attr_reader :token, :openid, :auth

	#点击登陆按钮跳转地址
	def Qq.redo(scope)
		AUTHURL + 'response_type=code&client_id='+ APPID + REDURL + '&scope=' + scope
	end

	#获取令牌:认证码code=params[:code],httpstat=request.env['HTTP_CONNECTION']
	def get_token(code,httpstat)
		#获取令牌
        @token=open(TOKENURL + 'grant_type=authorization_code&client_id=' + 
        			APPID + '&client_secret=' + APPKEY + '&code=' + code + 
        			'&state='+ httpstat + REDURL,
                    :ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE).read[/(?<=access_token=)\w{32}/]
        #获取Openid
        @openid=open(OPENIDURL + @token,
        			:ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE).read[/\w{32}/]
        #获取通用验证参数
        @auth='access_token=' + @token + '&oauth_consumer_key=' + APPID + '&openid=' + @openid
	end

	#获取用户信息:比如figureurl,nickname
	def get_user_info(auth)
		MultiJson.decode(open(GETUSERINFOURL + auth,
			:ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE).read.force_encoding('utf-8'))
	end
end

# 获取用户信息并保存的控制器(一般为首页)
	def home
		@posts = Post.all
		login_by_qq unless params[:code].nil?
	end

	private
		def login_by_qq
			begin
			    httpstat=request.env['HTTP_CONNECTION']
			    qq = Qq.new
			    token = qq.get_token(params[:code],httpstat)
			    qq_user_infor = qq.get_user_info(token)
			    # QQ登录操作
			    if @user = User.find_by_uid(qq_user_infor["nickname"].to_s + qq_user_infor["figureurl"].to_s)
			        sign_in_without @user
			    else
			    	# 创建新用户
					User.new do |user|
						# :uid =>qq_user_infor["nickname"].to_s + qq_user_infor["figureurl"].to_s,
						user.name = qq_user_infor["nickname"],
						# user.avatar = qq_user_infor["figureurl_2"]
						user.save!(validate: false)
					end
			    end
			    # 操作失败返回主页
			    rescue Exception =>e
			        redirect_to root_path
			  end
		end