Flask后端实践 连载十六 Flask实现微信Web端及APP端登录注册

tips:

  • 本文将实现微信Web端和APP端登陆注册
  • 本文基于python3编写
  • 代码仓库

项目场景

某天,项目经理说,项目上除了本身自带的登陆注册,也需要第三方的登陆注册。方便用户使用我们的产品。于是便开始加上微信登陆注册的功能。

实现流程

  1. 前端页面拉取微信授权二维码
  2. 用户扫码确认授权。
  3. 前端将授权码发送到后端。
  4. 后端将授权码发送到微信平台验证,获取用户信息及授权信息。
  5. 比较本平台用户信息,实现用户登陆和注册。

前置条件

  1. 安装flaskflask-sqlalchemyPyMySQL
  2. 在微信开放平台申请了账户并成为开发者。
  3. 创建网站应用和移动应用,申请成功之后会下发appidsecret,web和app的appidsecret不一样。
  4. 数据库设计
    • user(用户表,存储用户信息)

      字段 类型 含义
      id int 用户主键ID
      name string 用户名称
      age int 年龄
    • user_login_method(用户登陆方式表,存储不同登陆方式)

      字段 类型 含义
      id int 用户登陆方式主键ID
      user_id int 用户主键ID
      login_method string 用户登陆方式,WX微信,P手机
      identification string 用户登陆标识,微信ID或手机号
      access_code string 用户登陆通行码,密码或token
  5. 映射数据库映射数据库到model.py
    from flask_sqlalchemy import SQLAlchemydb = SQLAlchemy()class User(db.Model):"""用户表"""__tablename__ = 'user'id = db.Column(db.Integer, autoincrement=True, primary_key=True)# 用户姓名name = db.Column(db.String(20), nullable=False) # 用户年龄age = db.Column(db.Integer, nullable=False)  class UserLoginMethod(db.Model):"""用户登陆验证表"""__tablename__ = 'user_login_method'# 用户登陆方式主键IDid = db.Column(db.Integer, autoincrement=True, primary_key=True)  # 用户主键IDuser_id = db.Column(db.Integer, nullable=False) # 用户登陆方式,WX微信,P手机 login_method = db.Column(db.String(36), nullable=False) # 用户登陆标识,微信ID或手机号identification = db.Column(db.String(36), nullable=False)  # 用户登陆通行码,密码或tokenaccess_code = db.Column(db.String(36), nullable=True)
    

实现过程

  1. 前端拉取微信认证授权二维码,参考网站应用微信登录开发指南。此处只需要第一步,用户扫码确认之后获取到code传入后端。

  2. 获取授权凭证wx_login_or_register.get_access_code

    import json
    from urllib import parse, requestfrom model import UserLoginMethod, User, dbdef get_access_code(code, flag):"""获取微信授权码:param code:前端或app拉取的到临时授权码:param flag:web端或app端:return:None 或 微信授权数据"""# 判断是web端登陆还是app端登陆,采用不同的密钥。if flag == "web":appid = "web_appid"secret = "web_secret"elif flag == "app":appid = "app_appid"secret = "app_secret"else:return Nonetry:# 把查询条件转成url中形式fields = parse.urlencode({"appid": appid, "secret": secret,"code": code, "grant_type": "authorization_code"})# 拼接请求链接url = 'https://api.weixin.qq.com/sns/oauth2/access_token?{}'.format(fields) print(url)req = request.Request(url=url, method="GET")# 请求数据res = request.urlopen(req, timeout=10)# 解析数据access_data = json.loads(res.read().decode())print(access_data)except Exception as e:print(e)return None# 拉取微信授权成功返回# {# "access_token": "ACCESS_TOKEN", "expires_in": 7200,"refresh_token": "REFRESH_TOKEN",# "openid": "OPENID","scope": "SCOPE"# }if "openid" in access_data:return access_data# 拉取微信授权失败# {# "errcode":40029,"errmsg":"invalid code"# }else:return None
  3. 获取微信用户信息wx_login_or_register.get_wx_user_info

    def get_wx_user_info(access_data: dict):"""获取微信用户信息:return:"""openid = access_data.get("openid")access_token = access_data.get("access_token")try:# 把查询条件转成url中形式fields = parse.urlencode({"access_token": access_token, "openid": openid})# 拼接请求链接url = 'https://api.weixin.qq.com/sns/userinfo?{}'.format(fields)print(url)req = request.Request(url=url, method="GET")# 请求数据,超时10sres = request.urlopen(req, timeout=10)# 解析数据wx_user_info = json.loads(res.read().decode())print(wx_user_info)except Exception as e:print(e)return None# 获取成功# {# "openid":"OPENID",# "nickname":"NICKNAME",# "sex":1,# "province":"PROVINCE",# "city":"CITY",# "country":"COUNTRY",# "headimgurl": "test.png",# "privilege":[# "PRIVILEGE1",# "PRIVILEGE2"# ],# "unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL"## }if "openid" in wx_user_info:return wx_user_info#  获取失败# {"errcode":40003,"errmsg":"invalid openid"}else:return None
    
  4. 验证本地用户信息wx_login_or_register.login_or_register,关键的是比较微信用户信息中的unionid

    def login_or_register(wx_user_info):"""验证该用户是否注册本平台,如果未注册便注册后登陆,否则直接登陆。:param wx_user_info:拉取到的微信用户信息:return:"""# 微信统一IDunionid = wx_user_info.get("unionid")# 用户昵称nickname = wx_user_info.get("nickname")# 拉取微信用户信息失败if unionid is None:return None# 判断用户是否存在与本系统user_login = db.session(UserLoginMethod). \filter(UserLoginMethod.login_method == "WX",UserLoginMethod.identification == unionid, ).first()# 存在则直接返回用户信息if user_login:user = db.session.query(User.id, User.name).\filter(User.id == user_login.user_id).first()data = dict(zip(user.keys(), user))return data# 不存在则先新建用户然后返回用户信息else:try:# 新建用户信息new_user = User(name=nickname, age=20)db.session.add(new_user)db.session.flush()# 新建用户登陆方式new_user_login = UserLoginMethod(user_id=new_user.id,login_method="WX",identification=unionid,access_code=None)db.session.add(new_user_login)db.session.flush()# 提交db.session.commit()except Exception as e:print(e)return Nonedata = dict(id=new_user.id, name=User.name)return data
    
  5. Flask接口

    
    from flask import Flask
    from wx_login_or_register import get_access_code, get_wx_user_info, login_or_register
    from model import dbapp = Flask(__name__)
    app.config["SQLALCHEMY_DATABASE_URI"]='mysql+pymysql://root:mad123@localhost:3306/test?charset=utf8mb4'
    # 注册数据库连接
    db.app = app
    db.init_app(app)@app.route("/testWXLoginOrRegister",methods=["GET"])
    def test_wx_login_or_register():"""测试微信登陆注册:return:"""# 前端获取到的临时授权码code = request.args.get("code") # 标识web端还是app端登陆或注册flag = request.args.get("flag")# 参数错误if code is None or flag is None:return "参数错误"# 获取微信用户授权码access_code = get_access_code(code=code, flag=flag)if access_code is None:return "获取微信授权失败"# 获取微信用户信息wx_user_info = get_wx_user_info(access_data=access_code)if wx_user_info is None:return "获取微信授权失败"# 验证微信用户信息本平台是否有,data = login_or_register(wx_user_info=wx_user_info)if data is None:return "登陆失败"return dataif  ___name__ =="__main__":app.run()
  6. 测试访问http://127.0.0.1:5000/testWXLoginOrRegister即可。

总结

  • 本文大致实现了微信web和app端的登陆注册,具体需求具体分析。
  • 下一篇将介绍Flask实现手机验证码登录注册

Flask后端实践 连载十六 Flask实现微信Web端及APP端登录注册相关推荐

  1. Flask后端实践 连载十八 Flask输出PDF报表

    Flask后端实践 连载十八 Flask输出PDF报表 tips: 简单实现Flask输出PDF报表 本文基于python3编写 代码仓库 项目场景 由于项目是工程上的使用,不仅需要对采集的数据进行分 ...

  2. Flask后端实践 连载十四 Flask输出Word报表

    Flask后端实践 连载十四 Flask输出Word报表 tips: 简单实现Flask输出Word报表 本文基于python3编写 代码仓库 项目场景 由于项目是工程上的使用,不仅需要对采集的数据进 ...

  3. Flask后端实践 连载十三 Flask输出Excel报表

    Flask后端实践 连载十三 Flask输出Excel报表 tips: 简单实现Flask输出Excel报表 本文基于python3编写 代码仓库 项目场景 由于项目是工程上的使用,不仅需要对采集的数 ...

  4. Redis进阶实践之十六 Redis大批量增加数据

    原文:Redis进阶实践之十六 Redis大批量增加数据 一.介绍 有时候,Redis实例需要在很短的时间内加载大量先前存在或用户生成的数据,以便尽可能快地创建数百万个键.这就是所谓的批量插入,本文档 ...

  5. 单反相机的传奇—佳能单反50年辉煌之路(连载十六)

    连载十六:执着--旁轴的坚持 引言:旭光学在单反上的惹眼表现,不可能让其他相机大厂无动于衷,然而以高档旁轴相机起家的佳能,面对徕卡和日本光学的远击近攻,仍然在旁轴相机的开发上不遗余力,并且获得了意想不 ...

  6. 【转载】 javaweb学习总结(二十二)——基于Servlet+JSP+JavaBean开发模式的用户登录注册 - 孤傲苍狼 - 博 http://www.cnblogs.com/xdp-gacl/

    javaweb学习总结(二十二)--基于Servlet+JSP+JavaBean开发模式的用户登录注册 一.Servlet+JSP+JavaBean开发模式(MVC)介绍 Servlet+JSP+Ja ...

  7. Flask后端开发(二) - Flask的练习(入门)

    建议食用官方文档:Welcome to Flask - Flask Documentation (2.1.x)https://flask.palletsprojects.com/ 前言:避免文章篇幅过 ...

  8. fastreport masterdata每页都显示_ALIENTEK 阿波罗 STM32F767 开发板资料连载十六章 OLED 显示实验...

    1)实验平台:alientek 阿波罗 STM32F767 开发板2)摘自<STM32F7 开发指南(HAL 库版)>关注官方微信号公众号,获取更多资料:正点原子 http://weixi ...

  9. 编译器之后端原理(三十六)

    一.编译器的后端技术 1. 编译器的前端技术,重点是让编译器能够读懂程序,无结构的代码文本经过前端的处理以后,就变成了Token.AST和语义属性.符号表等结构化的信息,基于这些信息,可以实现简单的脚 ...

最新文章

  1. Nat. Mach. Intel. | IBM RXN: 深度学习在化学反应分类上大放异彩
  2. 驭下术:如何让下属老实听话?用这3招,让你不怒自威
  3. MySQL优化—工欲善其事,必先利其器之EXPLAIN
  4. MFC:怎么将程序窗口最小化到系统托盘
  5. php mysql随机记录,php – 从MySQL中选择可变数量的随机记录
  6. 【渝粤教育】国家开放大学2018年秋季 0109-21T公司财务 参考试题
  7. webstorm使用技巧
  8. C语言第五次博客作业
  9. 【Python】 [基础] 条件判断 与 循环 与dict和set
  10. 速成pytorch学习——4天中阶API示范
  11. Egret 之 消除游戏 开发 PART 6 Egret elimination game development PART 6
  12. mysql统计某一个数据库中有几张表
  13. 59 | 测试专栏特别放送 | 答疑解惑第七期
  14. html + css 实现淘宝首页(静态页面)
  15. FOI冬令营 Day1
  16. 人脸识别技术和人脸识别特征
  17. 输出边长为n的正六边形(c语言)
  18. 科大奥锐干涉法测微小量实验的数据,大学物理实验报告答案大全(实验数据)
  19. win7开不了机按f8修复计算机没反应,win7开不了机按f8没用怎么办
  20. std::cunction() 简单描述

热门文章

  1. Android 使用Jsoup解析网页批量获取图片
  2. 使用itools 给 ios 安装 app 测试包
  3. Java网络编程(一):五种I/O模型
  4. 5种主题Bootstrap后台模板HTML界面
  5. node(koa)完成微信公众号自动回复功能
  6. 浪潮nf5180m5服务器安装系统,浪潮英信服务器NF5180M5
  7. 微信企业付款接口API
  8. 今天看了公司的聘用合同,如有兼职需罚款10万元
  9. 如何让EDIUS中音频降噪
  10. java序列化如何实现_什么是java序列化,如何实现java序列化