1.创建SpringBoot项目
在线创建:https://start.spring.io
2.导入依赖
-
SpringWeb
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
-
Hutool:用来处理一些http请求、字符串处理、编解码、IO操作等
<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.7.14</version> </dependency>
3.提取接口
腾讯电脑管家的QQ登录地址:https://xui.ptlogin2.qq.com/cgi-bin/xlogin?appid=716027609&daid=383&style=33&theme=2&login_text=%E6%8E%88%E6%9D%83%E5%B9%B6%E7%99%BB%E5%BD%95&hide_title_bar=1&hide_border=1&target=self&s_url=https%3A%2F%2Fgraph.qq.com%2Foauth2.0%2Flogin_jump&pt_3rd_aid=101478239&pt_feedback_link=https%3A%2F%2Fsupport.qq.com%2Fproducts%2F77942%3FcustomInfo%3D.appid101478239
通天国际的QQ登录地址:https://graph.qq.com/oauth2.0/show?which=Login&display=pc&response_type=code&client_id=101963425&redirect_uri=https://www.tongtian.icu/login/qq/callback
通过哪个入口登录,用户扫码的时候提示的就是对应的产品,这里拿电脑管家继续往下演示。
3.1 获取二维码图片
https://ssl.ptlogin2.qq.com/ptqrshow?appid=716027609&e=2&l=M&s=3&d=72&v=4&t=0.33472448029234037&daid=383&pt_3rd_aid=101478239
3.2 校验扫码状态
https://ssl.ptlogin2.qq.com/ptqrlogin?u1=https%3A%2F%2Fgraph.qq.com%2Foauth2.0%2Flogin_jump&ptqrtoken=25702204&ptredirect=0&h=1&t=1&g=1&from_ui=1&ptlang=2052&action=0-0-1633807738528&js_ver=21100910&js_type=1&login_sig=enR8pbm6qeWQIu7C33CT*wpwg2upFruEL4lB6CB3wfaSacRtvHtAS2JbamaA1HdW&pt_uistyle=40&aid=716027609&daid=383&pt_3rd_aid=101478239&
很明显有两个不像固定值的值需要我们去处理。
-
login_sig
这个值在3.1接口的返回cookie中可以找到,字段为qrsig。
-
ptqrtoken
通过一波简单的Js逆向,可以看到这个值其实就是qrsig的hash33。
这里提供一组测试值方便大家调试对比,当你改写的算法能正确计算出结果之后,就可以进行下一步了。
原始值:enR8pbm6qeWQIu7C33CT*wpwg2upFruEL4lB6CB3wfaSacRtvHtAS2JbamaA1HdW
处理后:25702204
3.2.1 返回值
返回值 | 状态 |
---|---|
ptuiCB('66','0','','0','二维码未失效。(376448948)', '') | |
ptuiCB('67','0','','0','二维码认证中。(589318870)', '') | |
ptuiCB('0','0','...','登录成功!', '吉祥如意') | |
ptuiCB('65','0','','0','二维码已失效。(3618659338)', '') |
4.实现接口
4.1 QqAuthController
因为这里的ptqrtoken的算值方法比较简单,就直接改写成java了,复杂情况下可以使用脚本引擎直接执行js取值。
@RestController
public class QqAuthController {
static String ptqrshowUrl = "https://ssl.ptlogin2.qq.com/ptqrshow?appid=716027609&e=2&l=M&s=3&d=72&v=4&t=0.8414116405980268&daid=383&pt_3rd_aid=101478239";
static String ptqrloginUrl = "https://ssl.ptlogin2.qq.com/ptqrlogin?u1=https%3A%2F%2Fgraph.qq.com%2Foauth2.0%2Flogin_jump&ptqrtoken={{ptqrtoken}}&ptredirect=0&h=1&t=1&g=1&from_ui=1&ptlang=2052&action=0-0-1633807738528&js_ver=21100910&js_type=1&login_sig={{qrsig}}&pt_uistyle=40&aid=716027609&daid=383&pt_3rd_aid=101478239&";
/**
* 获取二维码
*/
@RequestMapping("/ptqrshow")
public void ptqrshow(HttpSession session, HttpServletResponse response) throws IOException {
HttpResponse httpResponse = HttpRequest
.get(ptqrshowUrl)
.disableCookie()
.timeout(5000)
.header("referer", "https://xui.ptlogin2.qq.com/")
.execute();
session.setAttribute("qrsig", httpResponse.getCookie("qrsig").getValue());
session.setAttribute("cookies", httpResponse.getCookies());
IoUtil.copy(httpResponse.bodyStream(), response.getOutputStream());
}
/**
* 校验登录
*/
@RequestMapping("/ptqrlogin")
public String ptqrlogin(HttpSession session) {
String qrsig = (String) session.getAttribute("qrsig");
String ptqrtoken = hash33(qrsig);
String url = ptqrloginUrl
.replace("{{ptqrtoken}}", ptqrtoken)
.replace("{{qrsig}}", qrsig);
List<HttpCookie> cookies = (List<HttpCookie>) session.getAttribute("cookies");
HttpResponse httpResponse = HttpRequest.get(url).disableCookie().timeout(5000).cookie(cookies).execute();
String qq = httpResponse.getCookieValue("superuin");
if(qq!=null){
// 登录成功
qq = qq.replace("o", "");
session.setAttribute("qq", qq);
}
return httpResponse.body();
}
/**
* ptqrtoken算值
* @param t qrsig
* @return
*/
public static String hash33(String t) {
int e, n, i;
for (e = 0, n = 0, i = t.length(); n < i; ++n) {
e += (e << 5) + ((int) t.charAt(n));
}
return String.valueOf(2147483647 & e);
}
}
4.2 UserController
获取个人信息
@RestController
public class UserController {
/**
* 获取用户信息
*/
@RequestMapping("/getUserInfo")
public UserInfo getUserInfo(HttpSession session, HttpServletResponse response) throws IOException {
String qq = (String) session.getAttribute("qq");
if(qq!=null){
// 然后去你的UserSerive中寻找绑定此QQ的账号,balabala...
return new UserInfo(qq);
}
// 未登录的情况下,重定向到登录页面...
response.sendRedirect("/login.html");
throw new RuntimeException("未登录");
}
/**
* 退出登录
*/
@RequestMapping("/logout")
public void logout(HttpSession session, HttpServletResponse response) throws IOException {
session.setAttribute("qq", null);
session.setAttribute("qrsig", null);
session.setAttribute("cookies", null);
response.sendRedirect("/login.html");
}
class UserInfo {
String qq;
public String getQq() {
return qq;
}
public void setQq(String qq) {
this.qq = qq;
}
public UserInfo(String qq) {
this.qq = qq;
}
}
}
4.3 index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--公共库地址,失效自行替换即可-->
<script src="https://cdn.staticfile.org/jquery/1.8.3/jquery.min.js"></script>
</head>
<body>
<div id="user-info" style="text-align: center">
<img id="user-head" src="">
<p id="user-uin"></p>
<a href="/logout">退出登录</a>
</div>
<script>
$(document).ready(function () {
// 加载个人信息
$.ajax({
url: "/getUserInfo",
success:function (data) {
$("#user-head").attr("src", "https://q4.qlogo.cn/g?b=qq&nk=" + data.qq+"&s=100");
$("#user-uin").text("你登录的号子是:"+data.qq);
},
error: function (e) {
// 跳转到登录页面
window.location = "/login.html"
}
})
});
</script>
</body>
</html>
4.4 login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--公共库地址,失效自行替换即可-->
<script src="https://cdn.staticfile.org/jquery/1.8.3/jquery.min.js"></script>
</head>
<body>
<div id="qrlogin" style="text-align: center">
<span id="loading">loading...</span>
<img id="qrcode" src="">
<p id="hint">请使用QQ手机版扫描二维码,安全登录,防止盗号。</p>
</div>
<script>
$(document).ready(function () {
function ptqrshow(){
// 加载二维码
$("#qrcode").attr("src", "/ptqrshow");
// 隐藏加载提示
$("#loading").hide();
// 扫码登录
window.ptqrlogin = window.setInterval(ptqrlogin, 1000);
}
function ptqrlogin() {
$.ajax({
url:"/ptqrlogin",
// 同步处理
async:false,
success:function (data) {
setTimeout(data,1);
},
error:function (e) {
window.clearTimeout(window.ptqrlogin);
$("#hint").text("请检查网络连接");
}
})
}
ptqrshow();
})
function ptuiCB(a,b,c,d,e,f,g) {
switch (a) {
case "67":
$("#hint").text ("二维码认证中");
break;
case "65":
$("#hint").text ( "二维码已失效");
break;
case "0":
$("#hint").text ("登录成功,请稍后...");
window.clearTimeout(window.ptqrlogin);
// 跳转到主页
setTimeout("window.location = '/index.html'", 1000*2);
break;
}
}
</script>
</body>
</html>
5.目录结构
6.效果演示
标题:二、另类QQ授权登录 - Java实现
分类:另类QQ第三方授权登录
链接:https://www.aqwdzy.com/content/126
版权:通天技术网(www.aqwdzy.com)所分享发布内容,部分为网络转载,如有侵权请立即联系方式,我们第一时间删除并致歉!
热烈庆祝通天技术网开业大吉
@通天技术网 热烈庆祝通天技术网开业大吉
热烈庆祝通天技术网开业大吉
@通天技术网 热烈庆祝通天技术网开业大吉