做qq登录前一直没发现,原来qq提供了2个平台:腾讯开放平台和qq互联平台,这两个分别对应去做qq的app登录和qq的pc或者手机h5登录
首先来看 pc端的qq登录:
1 QQ互联->网站接入 http://connect.qq.com/manage/index?apptype=web
2 按照要求填写开发者资料.重要一点是自己域名的 www.XX.com/XX 回调地址。
3 申请成功之后,你会得到一个APP ID和一个APP KEY了。这是登陆链接的需要的参数, 只有这二个值都在,你才可以进行后面的步骤。
4 开放平台授权地址:你们可以用自己申请的ID 和回调 地址 配置一个链接地址:https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=[YOUR_APPID]&redirect_uri=[YOUR_REDIRECT_URI]&scope=[THE_SCOPE]
请将client_id,redirect_uri,scope等参数值替换为你自己的 其中scope可以写死为:get_user_info 具体的可以看官方的文档:http://wiki.connect.qq.com/使用authorization_code获取access_token
5 点击会跳到QQ授权登陆
登录之后,跳回到你配置的回调地址,地址栏上会带有code,需要注意的是这个code有效期为10分钟,并且一个code只能使用一次,使用过后就不能再用了,这个code我这边是前端拿到之后传给我的,拿到这个code之后,我们才能进行下面的操作。
这里遇到2个坑:一个是,创建项目在qq互联里面创建,而文档却在qq开放平台里创建
第二个是写着配置顶级域名就可以了,实际上是不行的,比如配置 www.jiddn.com,理论上可以配置自己的回调地址为 www.jiddn.com/index 上,但是并不能,需要在qq互联里配置 www.jiddn.com/index ,才可以,在配置回调地址的时候,多个地址用;隔开,两个配置的地方都要带http或者https
https://graph.qq.com/oauth2.0/token?grant_type=authorization_code&client_id=[YOUR_APP_ID]&client_secret=[YOUR_APP_Key]&code=[The_AUTHORIZATION_CODE]&state=[The_CLIENT_STATE]&redirect_uri=[YOUR_REDIRECT_URI]
这里又有一个坑,因为他返回的不是纯json格式,而是这样的:
access_token=access_token&expires_in=expires_in&refresh_token=refresh_token
竟然是一个字符串,惊呆了,没办法,只能解析,而且解析的过程中发现如果报错的话,返回的不是字符串,也不是json,而是不知道啥格式:
没办法,只能进行转换格式:
将字符串和callback转成map,然后获取到access_token,进行下一步:
2.根据accesstoken获取openid
https://graph.qq.com/oauth2.0/me?access_token=YOUR_ACCESS_TOKEN
这个时候返回的是
callback( {“client_id”:“YOUR_APPID”,“openid”:“YOUR_OPENID”} ); 这种的,需要跟上面一样解析
3.使用Access Token以及OpenID来访问和修改用户数据
以调用get_user_info接口为例:
(1)发送请求到get_user_info的URL(请将access_token,appid等参数值替换为你自己的):
https://graph.qq.com/user/get_user_info?access_token=YOUR_ACCESS_TOKEN&oauth_consumer_key=YOUR_APP_ID&openid=YOUR_OPENID
(2)成功返回后,即可获取到用户数据
{
"ret":0,
"msg":"",
"nickname":"YOUR_NICK_NAME",
...
}
ret为0则成功,否则获取信息失败,拿不到昵称,报错,这样qq登录就成功了,注意这里是获取不到qq号的,只有qq昵称,然后可以将一些信息存储到数据库,和用户id对应,我建表的字段:其中发现mobile是多余的,可以不用存
最后进行简单的判断,用户qq登录后,拿唯一的union_id,暂时用openid,去查询这张表,如果有用户信息,则返回这个用户的信息,并且登录成功,否则跳转到绑定手机号界面,绑定手机号的时候,如果这个手机号是在平台注册过用户的,则直接绑定到那个用户上,否则我这里的逻辑是生成一个用户,昵称为手机号加随机字符,初始密码给一个,这里的逻辑无论是qq app pc还是wx app pc都是一样的
这样pc的qq登录就完成了,接下来看qq的app登录,其实逻辑和pc的基本一样,需要注意的是:code由安卓,ios那边生成传给我,我这里需要区分ios android和pc的类型,因为要配置不同的app key和app id,还有app端的qq在这里申请:http://op.open.qq.com/ 而不是之前的qq互联,拿到code之后,跟之前做一样的逻辑,但是会发现一个坑:qq没有像微信一样唯一的三方标识:unionid,只有openid,而且app端和pc端的openid是不一样的,无法当作唯一标识存入数据库,这个时候,发现在这里:http://wiki.connect.qq.com 开发者反馈。
只想说腾讯他妈的隐藏的真好。。在这里有生成unionid的方法,填表,发邮件,然后就可以去请求这个接口:表格怎么填,已经写的比较详细,就不说了,申请通过后,调用https://graph.qq.com/oauth2.0/me?access_token=ACCESSTOKEN&unionid=1去获取unionid
正确的Json返回结果 注意:返回的数据不是json格式
callback({
"client_id":"YOUR_APPID",
"openid":"YOUR_OPENID",
"unioid":"YOUR_UNIONID"
});
如果没有发表格申请,是会报错的,不会返回unionid,这个是唯一的了,把这个存到数据库里面,这样app和pc的qq登录就能同步了
经过测试,发现还有一个坑,就是qq包括wx,都存在昵称中存在表情,这个时候,如果数据库不做处理,就会报错,方法1,就是处理数据库,这个网上一大堆,我才用的是方法2,把特殊字符过滤掉,变成*,毕竟只是一个展示用:具体实现方法:
public String filterEmoji(String source) {
if (source == null) {
return source;
}
Pattern emoji = Pattern.compile("[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\u2600-\u27ff]",
Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE);
Matcher emojiMatcher = emoji.matcher(source);
if (emojiMatcher.find()) {
source = emojiMatcher.replaceAll("*");
return source;
}
return source;
}
就好了。
再总结一下,拿到code之后所有的请求,都是get方法,后台需要配置的qq相关的信息要6个,是pc ios android的appid和appkey,ios和android的appid和appkey都是不一样的。如果还有问题,就多看官方文档,有些隐藏的真的很深。