烽火村游戏活动中心

HOME> 活动中心> QQ 是怎样实现一键登录的

QQ 是怎样实现一键登录的

2025-12-10 10:13:52

大家应该都体验过腾讯系应用的一键登录功能(PC),当你的电脑上登陆了 QQ 之后,使用QQ快捷登录进行OAuth验证时不需要再手动输入账号和密码,点击自己的头像就可以成功登陆应用。

也许你也曾有过好奇她是如何实现的,今天我们就来复刻一个。

原理剖析当我们登陆QQ的时候有快捷登录,没登QQ的时候只有扫码登录,一定适合我们的电脑QQ进行了通信,但是浏览器权限非常低,在没有弹窗授权的情况下不可能直接和应用进行通信,可以猜一手通过HTTP我们可以使用Chrome的网络抓包工具来看一下到底是怎么实现的

经过仔细检查最终发现了这样一个请求,看样子时JSONP类型的请求,他的响应格式如下

var var_sso_uin_list = [{

"uin": ------,

"face_index": 0,

"gender": 0,

"nickname": "沿途の风景",

"client_type": ------,

"uin_flag": ------,

"account": ------

}];

ptui_getuins_CB(var_sso_uin_list);

再来看这个请求的地址,第一感觉就是请求了localhost,可以ping一下看一看IP

看样子腾讯是将这个域名解析到了127.0.0.1,调用该域名的接口时就会访问用户本机,而这个域名后面还有一个端口,我们再检查一下本机的4301端口

果不其然,看来QQ客户端就是监听了某个端口,快捷登录的数据就是从这里获取的。

剩下的就是OAuth的东西了,我们就不转门去研究了,这个应该是和QQ互联的借口相关。

复刻在知道实现原理之后我们就可以动手实现一个了,我们选择给予Electron来实现一个客户端(JS是万能的)。

首先初始化一个Electron的项目(不会Electron的可以简单了解一下,我后面会出一个Electron的学习笔记)。

可以利用NodeJS的内置模块http来启动一个服务,监听某一个端口,将对应路径的请求返回即可,http服务的代码如下

import { createServer } from 'http'

import { parse as parseUrl } from 'url'

import { parse as parseQs } from 'querystring'

let server;

export function openServer() {

closeServer();

server = createServer((req, res) => {

const url = req.url

const urlObj = parseUrl(url)

const qs = parseQs(urlObj.query)

if (urlObj.pathname === '/pt_get_uins') {

res.writeHead(200, { 'Content-Type': 'application/javascript; charset=utf-8' })

res.end(

'var var_sso_uin_list = [{' +

'"uin": 123456,' +

'"face_index": 0,' +

'"gender": 0,' +

'"nickname": "沿途の风景",' +

'"client_type": 123456,' +

'"uin_flag": 123456,' +

'"account": 123456' +

'}];' + qs.callback +

'(var_sso_uin_list);'

)

} else {

res.writeHead(400)

res.end('Not Found')

}

})

server.listen(8888)

}

export function closeServer() {

server && server.removeAllListeners();

server && server.close(() => {

console.log("服务接口关闭");

});

}

在这段代码中,我们启动了一个httpServer,这个server中针对指定的路径返回了之前我们解析出的QQ返回的文件格式,给响应设置了Content-Type为javascript,拼接了请求中传递的callback函数。

我们将这段代码添加到主进程代码中

import { app, BrowserWindow } from 'electron';

import { openServer } from './httpServer';

let mainWindow: BrowserWindow | null;

app.whenReady().then(() => {

mainWindow = new BrowserWindow({});

mainWindow.loadURL(process.argv[2]);

openServer()

})

这时启动应用即可体验效果,打开浏览器发送访问路径即可

具体的嵌入到应用中我们就不模拟了,就是将这个请求嵌入到业务组件中即可。

最新发表
友情链接