基本步骤
- 放置QQ登录按钮(设置路由,添加登录链接)
- 获取Authorization Code(获取认证码)
- 通过Authorization Code获取Access Token(通过认证码获取令牌)
- 使用Access Token来获取用户的OpenID(通过令牌获取用户标识,openid是此网站上唯一对应用户身份的标识,网站可将此ID进行存储便于用户下次登录时辨识其身份,或将其与用户在网站上的原有账号进行绑定。)
- 使用Access Token以及OpenID来访问和修改用户数据(比如get_user_info)
基本代码如下:
# 设置路由
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