web实现QQ第三方登录

开发步骤:

1、 注册成为QQ互联平台开发者,http://connect.qq.com/

2、准备一个可访问的域名,如dev.foo.com

3、创建网页应用,配置必要信息,其中包括域名以及回调地址; 其中域名需要验证,需确保对域名主机有足够的控制权限

4、 获取应用appID、appKey进行开发

登录流程:

开发平台的登录授权采取oauth2.0机制,这也是目前几乎所有互联网开放平台所采取的方式。



需更多了解oauth2.0可参考阮老师的文章:http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html

实现方式:

client-side

        流程:

        前端页面通过Implict方式 登录授权 -> 回调获得accessToken -> 获取openid -> 同步用户信息并登录

        为了保证数据安全,在获取用户信息并登录这一步必须由服务端实现。

        这种方式的开发相对便捷,也是后面的实战案例将要采取的方式。

server-side

        流程:

        由server端页面跳转到登录授权页面(Authorization code方式) -> 回调获得code -> 置换accessToken -> 获取openid -> 同步用户信息并登录

可参考:http://wiki.connect.qq.com/%E5%BC%80%E5%8F%91%E6%94%BB%E7%95%A5_server-side

SDK使用:

JSSDK  可快捷实现前端登录授权的功能,可自定制登录按钮

        使用文档:http://wiki.connect.qq.com/js_sdk%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E

        缺点:存在浏览器兼容风险,此外登录按钮UI的定制也存在受限

JavaSDK  屏蔽了oauth授权的复杂度,方便后端实现授权及api操作

        缺点:增加依赖jar包,项目容易变得臃肿,尤其是当前项目已经存在oauth功能实现时可不必采用。

案例实战:

   功能描述: clientside + server-side 通过QQ网页授权登录,并获取用户信息

开发环境准备:

修改hosts文件将dev.foo.com映射到127.0.0.1;

本地服务器以80端口启动, windows下可能会出现80端口被系统进程占用的情况,解决方法可参考http://www.cnblogs.com/littleatp/p/4414578.html

        本地服务器启动后,以dev.foo.com的域名进行访问,在QQ登录授权时可通过域名验证这一步

登录跳转页面:

   

        QQ登录跳转

       

       

   

   

           

AccessToken:--ExpireIn

           

OpenID:

   

   

   

功能描述

        页面在第一次打开时跳转到QQ登录授权页面;

        授权成功之后回到当前页面通过url参数(hash串)获得accessToken;

        此后可通过jsonp方式获取用户的openid,url如:https://graph.qq.com/oauth2.0/me?access_token=YOUR_ACCESS_TOKEN

获取到用户OpenID,返回包如下(JSONP方式获取):callback( {"client_id":"YOUR_APPID","openid":"YOUR_OPENID"} ) 

将access_token及openid传到服务端进行处理

server端获取用户信息:

/**

    * 登录结果

    *

    * @param access_token

    * @param openid

    */

    public static void login_result(String access_token, String openid) {

        //调用api获取qq用户信息

        QQUserInfo user = QQApi.getUserInfo(access_token, openid);

        //此时若取得user信息,则可以进行保存,并执行用户登录操作

        ....


        //登录成功后跳转

        redirect(xxx);

    }

QQApi的实现 :

/**

* QQ互联API

*

*

* 登录流程:

*

* 1 前端跳转qq授权页面

* 2 js获得access_token

* 3 通过jsonp方式获得openid

* 4 server端根据上传的access_token及openid获取用户信息,如昵称、头像

*

* 参考文档:

* http://wiki.connect.qq.com/%E5%BC%80%E5%8F%91%E6%94%BB%E7%95%A5_client-side#Step2.EF.BC.9A.E8.8E.B7.E5.8F.96AccessToken

*

*

* @author xxx

* @createDate 2015年3月10日

*

*/

public class QQApi {

    public static String appId = "xxx";

    public static String appSecret = "xxx";

    public static String baseUrl = "https://graph.qq.com";

    protected static final String URL_GET_USERINFO = baseUrl

            + "/user/get_user_info?access_token=%s&oauth_consumer_key=%s&openid=%s";

    protected static final long ACCESS_TIMEOUT = 15;

    protected static final String DEF_APP_TOKEN_EXPIRE = "3h";

    /**

    * 获取用户信息

    *

    *

    * http://wiki.connect.qq.com/get_user_info

    *

    *

    * 调用地址:

    * https://graph.qq.com/user/get_user_info

    * 参数

    *  access_token=*************&

    *  oauth_consumer_key=12345&

    *  openid

    *

    * 返回结果如下:

    * {

    *    "ret": 0,

    *    "msg": "",

    *    "is_lost": 0,

    *    "nickname": "小吞",

    *    "gender": "女",

    *    "province": "广东",

    *    "city": "广州",

    *    "year": "1993",

    *    "figureurl": "http://qzapp.qlogo.cn/qzapp/101207268/982C9FEADAF7B242C5069B8F390784BF/30",

    *    "figureurl_1": "http://qzapp.qlogo.cn/qzapp/101207268/982C9FEADAF7B242C5069B8F390784BF/50",

    *    "figureurl_2": "http://qzapp.qlogo.cn/qzapp/101207268/982C9FEADAF7B242C5069B8F390784BF/100",

    *    "figureurl_qq_1": "http://q.qlogo.cn/qqapp/101207268/982C9FEADAF7B242C5069B8F390784BF/40",

    *    "figureurl_qq_2": "http://q.qlogo.cn/qqapp/101207268/982C9FEADAF7B242C5069B8F390784BF/100",

    *    "is_yellow_vip": "0",

    *    "vip": "0",

    *    "yellow_vip_level": "0",

    *    "level": "0",

    *    "is_yellow_year_vip": "0"

    * }

    *

    *

    * @param accessToken

    * @return

    */

    public static QQUserInfo getUserInfo(String accessToken, String openid) {

        if (StringUtils.isEmpty(accessToken) || StringUtils.isEmpty(openid)) {

            return null;

        }

        String url = String.format(URL_GET_USERINFO, accessToken, appId, openid);

        String resultString = DefaultHttp.get(url, ACCESS_TIMEOUT, GlobalConstants.UTF_8);

        Logger.debug("[sso-qq]get userinfo. use url '%s'", url);

        QQUserInfo userinfo = JsonUtil.fromJson(resultString, QQUserInfo.class);

        if (userinfo == null || !userinfo.hasGot()) {

            Logger.debug("[sso-qq]get userinfo failed, with result of '%s'", resultString);

            return null;

        }

        Logger.debug("[sso-qq]get userinfo success, with result of '%s'", resultString);

        return userinfo;

    }

常见问题:

网页跳转提示 "redirect_uri_mismatch"

        通常是应用配置中的域名与当前开发服务器访问地址不一致导致,参照案例中的本地开发环境准备小节


api调用返回错误

        查看返回的ret字段,对于非0值的ret则表示异常结果,可通过以下地址查询错误原因:

http://wiki.connect.qq.com/%E5%85%AC%E5%85%B1%E8%BF%94%E5%9B%9E%E7%A0%81%E8%AF%B4%E6%98%8E


接口调用过于频繁或超过限制

        应用系统可做好access_token的存储,此外对于用户数据(昵称、头像)也做好缓存或持久化,以减少接口的调用频度。

你可能感兴趣的:(web实现QQ第三方登录)