文档章节

网站集成QQ登录功能

编程中国社区
 编程中国社区
发布于 2016/04/29 12:40
字数 1498
阅读 47
收藏 0
最近在做一个项目时,客户要求网站能够集成QQ登录的功能,以前没做过这方面的开发,于是去QQ的开放平台官网研究了一下相关资料,经过自己的艰苦探索,终于实现了集成QQ登录的功能,现在把相关的开发经验总结一下,希望对有这方面需求的朋友有所帮助。

一.前期准备

首先你需要登录QQ的开发平台注册一个账号,QQ互联平台官方地址:http://connect.qq.com/ 进去后注册一个开发账号,完了登录后台会有类似如下的一个后台,填好相关信息,具体可以参考下图。最后我们会有一个APP ID和APP KEY ,有了这两个东西才能实现后面的集成QQ登录功能。

二开发工作

当我们的账号审核后,QQ开发平台会给我们一个APP ID和APP KEY,有了这两个,我们就可以进行开发的工作了。
QQ的登录采用的是OAuth2.0协议,OAuth(开放授权)是一个开放标准,允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方网站或分享他们数据的所有内容。具体的内容可以参考QQ的API文档http://wiki.connect.qq.com/oauth2-0%e7%ae%80%e4%bb%8b
QQ的开发平台已经有PHP,JAVA,JS等版本的SDK了,如果是要用到这些语言进行开发的可以直接参考这些SDK,我这边直接讲一下ASP.NET版本(MVC)的开发。

第一步.先在WebConfig中的  <appSettings>节点下加入如下配置
<add key="QQAppID" value="QQ平台给的APP ID" />
<add key="QQAppKey" value="QQ开发平台给的APP KEY"/>
<add key="QQCallBack" value="http://www.mylanqiu.com/Account/QQConnect/"/>

<add key="QQAuthorizeURL" value="https://graph.qq.com/oauth2.0/authorize" />


第二步.在Controllers中加一个登陆的Action(我这边用的是MVC的开发方式,如果是传统.NET的可以直接在.aspx的Page_Load事件里加如下方法)
public ActionResult LoginQQ()
{
  string state = new Random(100000).Next(99, 99999).ToString();//随机数
  Session["QQState"] = state;
  string appID = ConfigurationManager.AppSettings["QQAppID"];
  string qqAuthorizeURL = ConfigurationManager.AppSettings["QQAuthorizeURL"];
  string callback = ConfigurationManager.AppSettings["QQCallBack"];
  string authenticationUrl = string.Format("{0}?client_id={1}&response_type=code&redirect_uri={2}&state={3}", qqAuthorizeURL, appID, callback, state);//互联地址
   return new RedirectResult(authenticationUrl);
 }
这一步主要是实现去QQ平台进行身份验证,直观点也就是点击后会去出现如下截图的画面

第三步.在点击了上图的同意登录后(也就是已经使用QQ号在QQ平台登录),QQ平台会通过我们上面配置的回调地址也就是我这边填的http://www.mylanqiu.com/Account/WeiboConnect/返回到这个页面,并会返回一个code给我们,我们到时会使用这个code再去QQ开发平台获取access_token,并通过这个access_token获取登录的相关用户信息。具体代码如下:
  /// <summary> 
        /// QQ回调页面 
        /// </summary>
        public ActionResult QQConnect()
        {
            if (!string.IsNullOrEmpty(Request.Params["code"]) && !string.IsNullOrEmpty(Request.Params["state"]))
            {
                var code = Request.Params["code"];
                var state = Request.Params["state"];
                string requestState = Session["QQState"] == null ? "" : Session["QQState"].ToString();
                if (state == requestState)
                {
                    try
                    {
                        QQOAuthHelper QAuthHelper = new QQOAuthHelper();//这是一个辅助类,代码会在下面给出
                        QQOauthInfo qqOauthInfo = QAuthHelper.GetOauthInfo(code);
                        string openID = QAuthHelper.GetOpenID(qqOauthInfo);//获取用的OpenID,这个ID是QQ给我们的用户的唯一ID,可以作为我们系统用户唯一性的判断存在我们自己的库中
                        Session["QQOpenID"] = openID;
                        string nickName = QAuthHelper.GetUserInfo(qqOauthInfo, openID);//获取用户的昵称
                        UserAccount userAccount = AccountBLL.GetUserAccountByOpenID(OAuthPlatform.QQ.ToString(), openID);
                        if (userAccount != null)//判断是否是已用该OpenID是否已在我们的库中,若已存在则允许登录
                        {
                            SetAuthCookie(userAccount);
                            Response.Write("<script>  window.opener.location.reload();window.close();</script>");
                        }
                        ViewData["NickName"] = nickName;
                    }
                    catch (Exception ex)
                    {
                        return new RedirectResult("~/Error/Error.htm");
                    }
                }
                else
                {
                    return new RedirectResult("~/Error/Error.htm");
                }
            }
            else
            {
                return new RedirectResult("~/Error/Error.htm");
            }
            return View();
        }
通过上面的步骤就可以实现网站集成QQ登录了。下面给出辅助类的源代码:
using System;
using System.Text;
using System.Configuration;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web;
using System.IO;
namespace Com.ABC.Mylanqiu.BLL
{
    public class QQOAuthHelper
    {
        string appID = ConfigurationManager.AppSettings["QQAppID"];
        string appKey = ConfigurationManager.AppSettings["QQAppKey"];
        /// <summary>
        /// 获取oauth信息
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        public QQOauthInfo GetOauthInfo(string code)
        {
            string callback = System.Web.HttpUtility.UrlEncode(ConfigurationManager.AppSettings["QQCallBack"], Encoding.UTF8);
            string url = string.Format("https://graph.qq.com/oauth2.0/token?grant_type={0}&client_id={1}&client_secret={2}&code={3}&redirect_uri={4}", "authorization_code", appID, appKey, code, callback);
            string res = LoadHtmlUserGetType(url, Encoding.UTF8);
            QQOauthInfo qqOauthInfo = new QQOauthInfo();
            qqOauthInfo.AccessToken = CutString(res, "access_token=", "&expires_in=");
            qqOauthInfo.ExpiresIn = CutString(res, "&expires_in=", "&refresh_token=");
            qqOauthInfo.RefreshToken = res.Split(new string[] { "&refresh_token=" }, StringSplitOptions.None)[1];
            return qqOauthInfo;
        }
        /// <summary>
        /// 截取字符串中两个字符串中的字符串
        /// </summary>
        /// <param name="str">字符串</param>
        /// <param name="startStr">开始字符串</param>
        /// <param name="endStr">结束字符串</param>
        /// <returns></returns>
        private string CutString(string str, string startStr, string endStr)
        {
            int begin, end;
            begin = str.IndexOf(startStr, 0) + startStr.Length; //开始位置   
            end = str.IndexOf(endStr, begin);            //结束位置     
            return str.Substring(begin, end - begin);   //取搜索的条数,用结束的位置-开始的位置,并返回     
        }
        /// <summary>  
        /// 通过GET方式获取页面的方法  
        /// </summary>  
        /// <param name="urlString">请求的URL</param>  
        /// <param name="encoding">页面编码</param>  
        /// <returns></returns>  
        public string LoadHtmlUserGetType(string urlString, Encoding encoding)
        {
            HttpWebRequest httpWebRequest = null;
            HttpWebResponse httpWebRespones = null;
            Stream stream = null;
            string htmlString = string.Empty;
            try
            {
                httpWebRequest = WebRequest.Create(urlString) as HttpWebRequest;
            }
            catch (Exception ex)
            {
                throw new Exception("建立页面请求时发生错误!", ex);
            }
            httpWebRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; Maxthon 2.0)";
            try
            {
                httpWebRespones = (HttpWebResponse)httpWebRequest.GetResponse();
                stream = httpWebRespones.GetResponseStream();
            }
            catch (Exception ex)
            {
                throw new Exception("接受服务器返回页面时发生错误!", ex);
            }
            StreamReader streamReader = new StreamReader(stream, encoding);
            try
            {
                htmlString = streamReader.ReadToEnd();
            }
            catch (Exception ex)
            {
                throw new Exception("读取页面数据时发生错误!", ex);
            }
            streamReader.Close();
            stream.Close();
            return htmlString;
        }
        /// <summary>
        /// 获取QQ账号的OpenID
        /// </summary>
        /// <param name="qqOauthInfo"></param>
        /// <returns></returns>
        public string GetOpenID(QQOauthInfo qqOauthInfo)
        {
            string res = LoadHtmlUserGetType("https://graph.qq.com/oauth2.0/me?access_token=" + qqOauthInfo.AccessToken, Encoding.UTF8);
            return CutString(res, @"openid"":""", @"""}");
        }
        /// <summary>
        /// 获取QQ昵称
        /// </summary>
        /// <param name="qqOauthInfo"></param>
        /// <param name="openID"></param>
        /// <returns></returns>
        public string GetUserInfo(QQOauthInfo qqOauthInfo, string openID)
        {
            string urlGetInfo = string.Format(@"https://graph.qq.com/user/get_user_info?access_token={0}&oauth_consumer_key={1}&openid={2}", qqOauthInfo.AccessToken,appID, openID);
            string resUserInfo = LoadHtmlUserGetType(urlGetInfo, Encoding.UTF8);
            return CutString(resUserInfo, @"""nickname"": """, @""",");
        }
    }
    public class QQOauthInfo
    {
        public string AccessToken { get; set; }
        public string ExpiresIn { get; set; }
        public string RefreshToken { get; set; }
    }
}

三.效果Demo

大家可以直接访问 http://www.mylanqiu.com看一下实际的效果,最后感谢大家的阅读,如对你有所帮助就多多转发,以帮助更多人,正所谓:赠人玫瑰 手有余香!如有不足,还请指正!

© 著作权归作者所有

编程中国社区
粉丝 0
博文 1
码字总数 1498
作品 0
大兴
私信 提问
joomlaQQ登录微博登录

joomla QQ登录 微信登录等第三方登录 在joomla网站上集成QQ,微信,支付宝,人人,明道,短信,微博登录现在已经成为可能。只需要安装ZMAX程序人开发的ZMAX第三方登录组件,一键就可以让你的...

张敏樱木花道
2015/04/09
585
0
smallwei/avue-cli

介绍 avue-cli是一款基于avue和element-ui完全开源、免费的企业后端产品前端集成解决方案,采用最新的前端技术栈,已经准备好了大部分的项目准备工作,你可以快速进行二次开发 文档 文档 文档...

smallwei
01/02
0
0
QQ玩说明

QQ玩市场包含四部分: PC端Web网站 http://www.qqwan.com/ PC端Web管理后台 http://www.qqwan.com/admincp.php honglou2014/szhl123 手机端Web网站 http://www.qqwan.com/mobile.php 手机端A......

l1fan
2015/03/06
8
0
QQ登录功能申请向第三方网站完全开放

热腾4月17日消息 QQ登录功能申请已经向第三方网站完全开放,现在只要登录腾讯社区开放平台填写网站资料便可以立即获取QQ登录相关的key和ID,无需等待审核。 通过“QQ登录”,用户能使用QQ帐号...

红薯
2011/04/17
7.9K
23
蝉知企业门户系统 5.3.4 正式版发布

蝉知企业门户系统是由业内资深开发团队开发的一款专向企业营销使用的企业门户系统,企业使用蝉知系统可以非常方便地搭建一个专业的企业营销网站,进行宣传,开展业务,服务客户。蝉知系统内置...

it1000001001
2016/07/15
1K
11

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周日乱弹 —— 我,小小编辑,食人族酋长

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @宇辰OSC :分享娃娃的单曲《飘洋过海来看你》: #今日歌曲推荐# 《飘洋过海来看你》- 娃娃 手机党少年们想听歌,请使劲儿戳(这里) @宇辰OSC...

小小编辑
今天
144
8
spring cloud

一、从面试题入手 1.1、什么事微服务 1.2、微服务之间如何独立通讯的 1.3、springCloud和Dubbo有哪些区别 1.通信机制:DUbbo基于RPC远程过程调用;微服务cloud基于http restFUL API 1.4、spr...

榴莲黑芝麻糊
今天
2
0
Executor线程池原理与源码解读

线程池为线程生命周期的开销和资源不足问题提供了解决方 案。通过对多个任务重用线程,线程创建的开销被分摊到了多个任务上。 线程实现方式 Thread、Runnable、Callable //实现Runnable接口的...

小强的进阶之路
昨天
6
0
maven 环境隔离

解决问题 即 在 resource 文件夹下面 ,新增对应的资源配置文件夹,对应 开发,测试,生产的不同的配置内容 <resources> <resource> <directory>src/main/resources.${deplo......

之渊
昨天
8
0
详解箭头函数和普通函数的区别以及箭头函数的注意事项、不适用场景

箭头函数是ES6的API,相信很多人都知道,因为其语法上相对于普通函数更简洁,深受大家的喜爱。就是这种我们日常开发中一直在使用的API,大部分同学却对它的了解程度还是不够深... 普通函数和...

OBKoro1
昨天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部