• 流程分析
  • 示例代码

流程分析

https://wx.qq.com/页面

<div class="qrcode" ng-class="{hide: isScan || isAssociationLogin || isBrokenNetwork}"><img class="img" mm-error="qrcodeException()" ng-class="{'qrcode_expired': isNeedRefresh}" mm-src="https://login.weixin.qq.com/qrcode/Ie_lVu7qmQ==" mm-src-load="qrcodeLoad" mm-src-parallel="" mm-src-timeout="10" mm-src-retry-count="2" src="https://login.weixin.qq.com/qrcode/Ie_lVu7qmQ=="><div ng-show="!isNeedRefresh" class=""><p class="sub_title">使用手机微信扫码登录</p><p class="sub_desc">网页版微信需要配合手机使用</p></div><div ng-show="isNeedRefresh" class="ng-hide"><div class="refresh_qrcode_mask"><i class="icon-refresh" ng-class="{rotateLoading: isRotateLoading}" ng-click="refreshQrcode()"></i></div><p class="refresh_tips">二维码失效,点击刷新</p></div></div>

我们看下src="https://login.weixin.qq.com/qrcode/Ie_lVu7qmQ=="图片式如何生成的呢?

由此我们得知web微信,在输出https://wx.qq.com/时候,会发起https://login.wx.qq.com/jslogin?appid=wx782c26e4c19acffb&redirect_uri=https%3A%2F%2Fwx.qq.com%2Fcgi-bin%2Fmmwebwx-bin%2Fwebwxnewloginpage&fun=new&lang=zh_CN&_=1525767248719请求,返回window.QRLogin.code = 200; window.QRLogin.uuid = "Ie_lVu7qmQ==";响应,
返回的response如下:

window.QRLogin.code = 200; window.QRLogin.uuid = "Ie_lVu7qmQ==";

然后拿到uuid,这里式Ie_lVu7qmQ==,然后渲染到html生成图片

同时在像微信服务器发起如下请求,

https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=wbvMiDtJMw==&tip=1&r=-1055033147&_=1525768422635

然后进行检测,看是否有手机扫码登陆,微信服务器处于pending状态,一直在等待手机扫码登陆,如果在某个时间段(大概半分钟),没有手机扫码登陆,就返回408状态码,然后再次微信服务器处于pending状态

以下式window.code=408;响应截图

然后用手机扫码操作

ret = requests.get(check_url)
print("ret.text~~~~~~~",ret.text)

输出如下

ret.text~~~~~~~ window.code=201;window.userAvatar = 'data:img/jpg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0llSiiGBDoooomB/9k=';

然后在不登陆的情况下,依然式pending状态

手机端点击登陆,返回如下

window.code=200;
window.redirect_uri="https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket=AbczicMqBfNXxYuJs5G0CbRy@qrticket_0&uuid=oamap_bsaQ==&lang=zh_CN&scan=1525770582";

然后会继续在redirect_uri发请求

https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket=ARsBaAiUYgJbySWbtovgZyVd@qrticket_0&uuid=Ibo3sJnmJQ==&lang=zh_CN&scan=1525771779&fun=new&version=v2&lang=zh_CN


返回结果如下:

返回的结果式xml格式:

<error>
<ret>0</ret>
<message></message>
<skey>@crypt_56c6e845_49bcf817dfc65bb4142170e355cf0ab2</skey
><wxsid>W7TXjDJ6pmok5Sbm</wxsid>
<wxuin>2404580303</wxuin>
<pass_ticket>OHHPpM8kNYzmK7XrKaYDJ3OtO7HldKT2REIuj148Fs%2FKNXEIOVKz0Ip%2FW6HbYgh</pass_ticket>
<isgrayscale>1</isgrayscale>
</error>

然后带着xml进行数据初始化:

然后渲染页面信息即可

示例代码

from flask import Flask, request, render_template, session, jsonify
import time
import requests
import re
from bs4 import BeautifulSoup
import jsonapp = Flask(__name__)
app.debug = True
app.secret_key = 'asdf3sdfsdf'def xml_parser(text):dic = {}soup = BeautifulSoup(text, 'html.parser')div = soup.find(name='error')for item in div.find_all(recursive=False):dic[item.name] = item.textreturn dic@app.route('/login', methods=['GET', 'POST'])
def login():if request.method == 'GET':ctime = str(int(time.time() * 1000))qcode_url = "https://login.wx.qq.com/jslogin?appid=wx782c26e4c19acffb&redirect_uri=https%3A%2F%2Fwx.qq.com%2Fcgi-bin%2Fmmwebwx-bin%2Fwebwxnewloginpage&fun=new&lang=zh_CN&_={0}".format(ctime)ret = requests.get(qcode_url)qcode = re.findall('uuid = "(.*)";', ret.text)[0]session['qcode'] = qcodereturn render_template('login.html', qcode=qcode)else:pass@app.route('/check_login')
def check_login():"""发送GET请求检测是否已经扫码、登录https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=QbeUOBatKw==&tip=0&r=-1036255891&_=1525749595604:return:"""response = {'code': 408}qcode = session.get('qcode')ctime = str(int(time.time() * 1000))check_url = "https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid={0}&tip=0&r=-1036255891&_={1}".format(qcode, ctime)ret = requests.get(check_url)print("ret.text~~~~~~~", ret.text)if "code=201" in ret.text:# 扫码成功src = re.findall("userAvatar = '(.*)';", ret.text)[0]response['code'] = 201response['src'] = srcelif 'code=200' in ret.text:# 确认登录print("code=200~~~~~~~", ret.text)redirect_uri = re.findall('redirect_uri="(.*)";', ret.text)[0]# 向redirect_uri地址发送请求,获取凭证相关信息redirect_uri = redirect_uri + "&fun=new&version=v2"ticket_ret = requests.get(redirect_uri)ticket_dict = xml_parser(ticket_ret.text)session['ticket_dict'] = ticket_dictresponse['code'] = 200return jsonify(response)@app.route('/index')
def index():"""用户数据的初始化https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r=-1039465096&lang=zh_CN&pass_ticket=q9TOX4RI4VmNiHXW9dUUl1oMzoQK2X2f3H3kn0VYm5YGNwUMO2THYMznv8DSXqp0:return:"""ticket_dict = session.get('ticket_dict')init_url = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r=-1039465096&lang=zh_CN&pass_ticket={0}".format(ticket_dict.get('pass_ticket'))data_dict = {"BaseRequest": {"DeviceID": "e750865687999321","Sid": ticket_dict.get('wxsid'),"Uin": ticket_dict.get('wxuin'),"Skey": ticket_dict.get('skey'),}}init_ret = requests.post(url=init_url,json=data_dict)init_ret.encoding = 'utf-8'user_dict = init_ret.json()print(user_dict)# for user in user_dict['ContactList']:#     print(user.get('NickName'))return render_template('index.html', user_dict=user_dict)if __name__ == '__main__':app.run()

login页面

<!DOCTYPE html>
<html lang="zh-cn">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Title</title>
</head>
<body><div style="width: 200px;margin: 0 auto"><h1 style="text-align: center">微信登录</h1><img id="img" style="height: 200px;width: 200px;" src="https://login.weixin.qq.com/qrcode/{{qcode}}" alt=""></div><script src="/static/jquery-1.12.4.js"></script><script>$(function () {checkLogin();})function checkLogin() {$.ajax({url:'/check_login',type:'GET',dataType:'JSON',success:function (arg) {if(arg.code === 201){// 扫码$('#img').attr('src',arg.src);checkLogin();}else if(arg.code === 200){// 重定向到用户列表location.href = '/index'}else{checkLogin();}}})}</script></body>
</html>

index.html

<!DOCTYPE html>
<html lang="zh-cn">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Title</title>
</head>
<body><h1>欢迎登录:{{user_dict.User.NickName}}</h1><h3>最近联系人</h3><ul>{% for user in user_dict.ContactList%}<li>{{user.NickName}}</li>{% endfor %}</ul>
</body>
</html>

测试效果图:

Flask--网页微信登陆示例相关推荐

  1. python实现网页微信登陆_django 微信网页授权登陆的实现

    一.准备工作 0x00 开发前准备 服务号!!! 微信认证. 备案过的域名. 服务器. 0x01 手动触发dns更新 0x02 配置业务域名 0x03 将服务器请求转发到本地 修改服务器的 /etc/ ...

  2. uniapp - 超详细的 H5 公众号网页微信登录示例代码,提供从 0-1 公众号配置及详细注释代码(站在新手小白的角度)第三方微信授权登录的实现!!

    介绍 目前示例是 "点击按钮登录",你也可以改为 "一进页面就登录" ,可随意改造. 百度的教程都太乱了,而且功能都有一定问题.本文主要讲解 uniapp H5 ...

  3. CAS SSO 4.0.x 集成OAuth(微信登陆示例)

    由于公司需要cas集成微信.但是在网上没有找到相应的示例.然后我就跑到官网上去找了一下CAS怎么集成OAuth的.这是基于pac4j-oauth-1.4.1.jar包org.pac4j.oauth.c ...

  4. 微信OAuth2网页授权登陆接口

    微信OAuth2网页授权登陆接口,微信OAuth2网页授权登陆接口,在你的网站上放上可以扫码登陆,会不会吸引更多用户去注册,现在你只需要简单的配制一下就可以轻松实现,还不快点拿走,微信扫码登陆接口开发 ...

  5. itchat库 账号安全无法登陆网页微信

    itchat库 账号安全无法登陆网页微信 无聊学习itchat库时,碰到的问题.却告知,再三感谢!!! import itchat, json# hotReload表示热部署,这样调试的时候就不用频繁 ...

  6. php微信登录app接口开发文档,PHP微信OAuth2网页授权登陆接口

    微信OAuth2网页授权登陆接口,微信OAuth2网页授权登陆接口,在你的网站上放上可以扫码登陆,会不会吸引更多用户去注册,现在你只需要简单的配制一下就可以轻松实现,还不快点拿走,微信扫码登陆接口开发 ...

  7. openid java_微信小程序调用微信登陆获取openid及java做为服务端示例

    一.微信小程序 第一步:调用 wx.login获取code 文档地址 第二步:判断用户是否授权读取用户信息 文档地址 第三步:调用wx.getUserInfo读取用户数据 文档地址 第四步:由于小程序 ...

  8. python flask 微信_使用Flask创建微信公众号

    基于Python3的Flask微信公众号后台这次先用Flask为微信公众号做个后台.微信公众号后台一般对性能各方面要求并不高,这里我们以新浪SAE为例,其他已解析域名的服务器同理.整个过程比较简单,算 ...

  9. AbpVnext 扩展企业微信扫码登录(钉钉登陆、短信登陆、微信登陆等)Vue框架

    目录 1.开始开发准备 1.1 企业微信扫码登陆接入流程 1.2 开启网页授权登陆 1.3 构造独立窗口登陆二维码 1.4 构造内嵌登陆二维码 @@登陆顺序: 1. 发现文档配置 2. 获取token ...

  10. python微信库有哪些_GitHub - zwczou/weixin-python: 微信SDK - 包括微信支付,微信公众号,微信登陆,微信消息处理等...

    微信SDK 提供微信登陆,公众号管理,微信支付,微信消息的全套功能 文档目录 如果需要单独使用其中的某些模块,可以见文档目录的具体模块 如果需要组合在一起可以参考快速开始 目录 安装 使用pip su ...

最新文章

  1. IBM DS300 安装
  2. 【伙伴故事】智慧厨电接入华为云+HarmonyOS,你的未来厨房长这样
  3. linux export 生效_Linux之提高命令行的工作效率
  4. 如何实现一平台多系统_自动化设备数据采集系统如何实现
  5. document.ready和window.onload
  6. 目标检测(十九)--SoftNMS
  7. 四川省计算机考试模拟试题,2020年自考计算机基础应用模拟试题
  8. 十五种小游戏代码(有0积分下载的哦)
  9. DDos攻击防御策略
  10. 少年中国说 梁启超
  11. JavaScript:分支流程控制switch语句详解
  12. 非主流图片制作,手机图片制作
  13. ubuntu下搭建不同端口网站
  14. YUVPlayer: 基于Android平台的YUV视频原始数据播放器
  15. Flume常用组件详解之Source
  16. 【QGIS入门实战精品教程】4.8:QGIS如何下载SRTM数字高程模型DEM?
  17. IOS 移动端视频播放不全屏
  18. 新手小白初学Java(一)一些简单知识
  19. Deep Laplacian Pyramid Networks for Fast and Accurate Super-Resolution
  20. 设计师必须掌握的交互知识

热门文章

  1. 字节跳动实习生转正工资_【有效】字节跳动(头条/抖音)日常实习生内推
  2. postfix(邮件服务器)说明与postconfig命令详解
  3. 软件测试工程师的职业规划
  4. google,翻译英文网站
  5. 【转】ASP.NET Core 2.0 支付宝当面付之扫码支付
  6. excel取消隐藏_这个毁人无数的Excel黑洞,却成就一批最牛X的高手
  7. 小明左右手分别拿两张纸牌:黑桃10和红心8,现在交换手中的牌。编写并输出互换后的结果,输出结果如图所示
  8. 搜狗输入法关闭快捷键
  9. raid读写速度对比_组建RAID 0前后的读写速度对比
  10. 阿里云(飞天)里的 盘古