python实现微信小程序用户登录、模板推送


Posted in Python onAugust 28, 2019

Python 实现微信小程序的用户登录

小程序可以通过官方提供的登录邓丽来获取用户身份的标示, 具体文档可以参考 官方文档, 通过流程时序可以看到, 对于需要和前端配合的服务端开发, 主要实现的就是通过小程序提供的 code 换取用户的 openid 和 session_key, 并用换取到的 openid 和 secret_key 作为自定义的登录态. 分析后得知, 作为小程序后端的开发, 主要实现以下几部分内容:

  • 提供一个 HTTP 接口, 供小程序方使用, 传递code;
  • 换取用户身份标识;
  • 维护一个自定义的登录态;
  • 需要存储用户的 openid , 以备后续使用.

1.提供给小程序一个 HTTP 接口, 接口而使用 Tornado 框架

简化阐述, 代码没有做异常处理

class LoginHandler(RequestHandler):
 def post(self):
 req_data = json.loads(self.request.body)
 js_code = req_data.get('js_code')
 
 # 开始换取用户的信息
 user_info = get_user_info(js_code=js_code)
 openid = user_info['openid']
 session_key = user_info['session_key']
 user_uuid = str(uuid.uuid4()) # 暴露给小程序端的用户标示
 
 # 用来维护用户的登录态
 User.save_user_session(
   user_uuid=user_uuid,
   openid=openid,
   session_key=session_key
 )
 
 # 微信小程序不能设置cookie, 把用户信心存在了headers中
 self.set_header('Authorization', user_uuid)
 # 存储用户信息
 User.save_user_info(open_id=openid)
 self.set_status(204)

2.换取用户身份标示, 直接使用 Requests包 请求微信的相关接口, 获取数据

def get_user_info(js_code):

 req_params = {
 "appid": 'app_id', # 小程序ID
 "secret": 'secret', # 小程序 secret
 "js_code": js_code,
 "grant_type": 'authorization_code'
 } 
 req_resutl = requests.get('https://api.weixin.qq.com/sns/jscode2session', params=req_params, timeout=3, verify=False)
 return req_result.json()

3.维护一个自定义的登录态, 使用 Redis

user_redis = StrictRedis.from_url('redis//localhost:6379')

class User(object):
 REDIS_EXPIRES = 7 * 24 * 60 * 60
 
 @classmethod
 def save_user_session(cls, user_uuid, openid, session_key):
 user_session_value = {
 'openid':openid,
 'session_key':session_key
 }
 user_session_key = 'US:' + user_uuid
 with user_redis.pipeline(transaction=False) as pipe:
 pipe.hmset(user_session_key, user_session_value)
 pipe.expire(user_session_key, cls.REDIS_EXPIRES)
 pipe.execute()

4.存储用户信息, 以备后用, ORM使用 SQLAlchemy

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base

# mysql 相关设置
engine = create_engine('mysql://root:pwd@localhost/wechat')
conn = engine.connect()

Base = declarative_base()
Base.metadata.reflect(engine)
tables = Base.metadata.tables

class User(object):
 table = tables['user']

 @classmethod
 def save_user_info(cls, open_id):
 # 存储用户信心
 sql = cls.table.insert().values(open_id=open_id)
 conn.execute(sql)

SQL 语句

CREATE TABLE `user`(
 `id` int(20) unsigned NOT NULL AUTO_INCREMENT,
 `open_id` varchar(32) NOT NULL COMMENT '用户 open_id',
 `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
 `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
 PRIMARY KEY (`id`),
 KEY `idx_oid` (`open_id`)
) ENGINE=InnoDB default CHARSET=utf8mb4;

Template: 通过代码发送微信模板消息

import json

import requests
from redis import StrictRedis
from tornado.web import RequestHandler

redis = StrictRedis.from_url('redis//localhost:6379')

def get_access_token():
 payload = {
 'grant_type': 'client_credential',
 'appid': 'appid',
 'secret': 'secret'
 }
req = requests.get('https://api.weixin.qq.com/cgi-bin/token', params=payload, timeout=3, verify=False)
access_token = req.json().get('access_token')
redis.set('ACCESS_TOKEN', access_token)

class FormHandler(RequestHandler):
 def post(self):
 req_data = self.request.body
 req_data = json.loads(req_data)
 form_id = req_data.get('from_id')
 remplate_push(form_id) # 使用消息进行模板推送
 
def template_push(form_id):
 data = {
 "touser": 'open_id',
 "template_id": 'template_id',
 "page": 'pages/index/index',
 "form_id": form_id,
 "data":{
 "keyword1":{
 "value": "value"
 }
 }
 "emphasis_keyword": ''
 }
 access_token = redis.get('ACCESS_TOKEN')
 push_url = 'https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token={}'.format(access_token)
 requests.post(push_url, json=data, timeout=3, verify=False)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python发送form-data请求及拼接form-data内容的方法
Mar 05 Python
Python处理JSON时的值报错及编码报错的两则解决实录
Jun 26 Python
python字符串中的单双引
Feb 16 Python
Python中property函数用法实例分析
Jun 04 Python
python实现简易动态时钟
Nov 19 Python
python中bytes和str类型的区别
Oct 21 Python
Pandas DataFrame中的tuple元素遍历的实现
Oct 23 Python
使用pyqt 实现重复打开多个相同界面
Dec 13 Python
pytorch数据预处理错误的解决
Feb 20 Python
python根据完整路径获得盘名/路径名/文件名/文件扩展名的方法
Apr 22 Python
python使用scapy模块实现ping扫描的过程详解
Jan 21 Python
python库Tsmoothie模块数据平滑化异常点抓取
Jun 10 Python
使用Python脚本zabbix自定义key监控oracle连接状态
Aug 28 #Python
django删除表重建的实现方法
Aug 28 #Python
Python Django 前后端分离 API的方法
Aug 28 #Python
django重新生成数据库中的某张表方法
Aug 28 #Python
PyQt5+Caffe+Opencv搭建人脸识别登录界面
Aug 28 #Python
关于Python核心框架tornado的异步协程的2种方法详解
Aug 28 #Python
python使用celery实现异步任务执行的例子
Aug 28 #Python
You might like
PHP中调用JAVA
2006/10/09 PHP
ThinkPHP公共配置文件与各自项目中配置文件组合的方法
2014/11/24 PHP
php查询mysql数据库并将结果保存到数组的方法
2015/03/18 PHP
ucenter中词语过滤原理分析
2016/07/13 PHP
IE7中javascript操作CheckBox的checked=true不打勾的解决方法
2009/12/07 Javascript
asp.net 30分钟掌握无刷新 Repeater
2011/09/16 Javascript
js实现点击添加一个input节点
2014/12/05 Javascript
浅析Javascript中“==”与“===”的区别
2014/12/23 Javascript
jQuery右下角旋转环状菜单特效代码
2015/08/10 Javascript
jQuery Ajax使用FormData对象上传文件的方法
2016/09/07 Javascript
KnockoutJS 3.X API 第四章之表单value绑定
2016/10/10 Javascript
vue+webpack实现异步组件加载的方法
2018/02/03 Javascript
layui前端框架之table表数据的刷新方法
2018/08/17 Javascript
ES6基础之解构赋值(destructuring assignment)
2019/02/21 Javascript
微信小程序云开发实现增删改查功能
2019/05/17 Javascript
vue中keep-alive,include的缓存问题
2019/11/26 Javascript
详解Vue的mixin策略
2020/11/19 Vue.js
[01:04:01]2014 DOTA2国际邀请赛中国区预选赛 5 23 CIS VS DT第一场
2014/05/24 DOTA
python连接池实现示例程序
2013/11/26 Python
python实现根据月份和日期得到星座的方法
2015/03/27 Python
利用python将pdf输出为txt的实例讲解
2018/04/23 Python
对Python模块导入时全局变量__all__的作用详解
2019/01/11 Python
Python递归及尾递归优化操作实例分析
2020/02/01 Python
浅谈python 调用open()打开文件时路径出错的原因
2020/06/05 Python
如何用用Python将地址标记在地图上
2021/02/07 Python
美国著名的团购网站:Woot
2016/08/02 全球购物
鉴定评语大全
2014/05/05 职场文书
先进事迹演讲稿
2014/09/01 职场文书
小区的门卫岗位职责
2014/10/01 职场文书
民事和解协议书格式
2014/11/29 职场文书
2015年教务工作总结
2015/05/23 职场文书
运动会通讯稿600字
2015/07/20 职场文书
四群教育工作总结
2015/08/10 职场文书
2019学生会干事辞职信
2019/06/27 职场文书
Jupyter notebook 不自动弹出网页的解决方案
2021/05/21 Python
Java实现简易的分词器功能
2021/06/15 Java/Android