微信:API网关Kong+Flask+Mongodb+阿里云短信构造微信网站扫码登录+微信小程序登录
一 概述
微信登录十分便捷,客户都从微信中来,处理微信的的接口就很关键。
以微信扫码登录确认为自然人可以防止爬虫爬取访问。
二 数据表
用户表:user _id,mongodb默认生成objectID user_id = str(uuid.uuid4()) 自己建立的用户唯一标志 user_type = GUEST/CONSUMER 自己设置的枚举用户类型区分用户消费者还是游客 consumer_id = get_consumer_id(user_id) 或者 get_consumer_id(unionid) API网关kong的唯一用户标志 unionid = get_wechat_unionid() 微信网站、公众号、小程序等的统一识别ID,区别于单服务的openID wechat_info —token_info 扫码登录的微信token/user_info token信息和用户信息 contact_info = None 记录用户的姓名,手机号码,公司等表单信息 create_time = "2018-05-25 16:19:41” 创建时间,第一次访问记录,以后每次访问不修改 last_time = "2018-05-25 16:19:41” 第一次以后的访问时间每次重置此选项 微信扫描记录表:scans _id,mongodb默认生成objectID user_id,str(uuid.uuid4()) 自己建立的用户唯一标志 user_type,GUEST/CONSUMER 自己设置的枚举用户类型区分用户消费者还是游客 access_time,"2018-05-25 16:19:41” 创建时间,第一次访问记录,以后每次访问重置 headers:dict(request.headers) 用户访问来源信息包含重要的referer 电话验证码表:phone_code _id,mongodb默认生成objectID phone:用户表单输入的手机号 code:用户点击发送验证码的阿里云短信验证码
三 业务逻辑:
这里的申请试用是说可以去客户公司部署,不是简单的尝试使用
业务逻辑(1):申请试用—>网站微信扫码登录—>填写手机,公司,试用理由等表单提交—>试用审核中….
业务逻辑(2):产品演示—>网站微信扫码登录—>到达演示访问限制次数—>填写手机,公司,试用理由等表单提交—>试用审核中….
业务逻辑(3):微信小程序授权登录—>试用审核中….
四 程序逻辑
确保网关启动,flask程序启动,mongodb数据库启动并连接
详细接口查看 ,微信开放平台网站应用接口
点击申请试用利用微信接口生成二维码,用户扫描二维码,返回授权码code给后端,后端根据code请求token以及openid,后端根据openID获取用户信息以及unionid。
(1)查看表中有无unionid,如果没有就创建新用户,把信息插入用户表user,并且将访问记录插入scans
# 用户第一次访问所以生成userID,并将unionID和consumer_id写入数据库 user_id = str(uuid.uuid4()) consumer_id = get_consumer_id(user_id) if consumer_id: key, secret, created_at = get_consumer_credentials(consumer_id) token = get_jwt_token(consumer_id, key, secret, created_at) set_limit_by_consumer_id(consumer_id) user = get_users_dict(token_info=token_content, user_info=user_content, user_id=user_id, user_type=GUEST, unionid=unionid, consumer_id=consumer_id, create_time=ts1, ) scan = get_scans_dict(user_id=user_id, user_type=GUEST, headers=request.headers, create_time=ts1, ) mongo.db.users.insert_one(user) mongo.db.scans.insert_one(scan)
(2)如果有unionID,最后访问时间更新user表中,并且将访问记录插入scans
user_id = unionid_obj.get("user_id") consumer_id = unionid_obj.get('consumer_id') key, secret, created_at = get_consumer_credentials(consumer_id) token = get_jwt_token(consumer_id, key, secret, created_at) scan = get_scans_dict(user_id=user_id, user_type=GUEST, headers=dict(request.headers), create_time=ts1, ) mongo.db.scans.insert_one(scan) mongo.db.users.update({'user_id': user_id}, {'$set': {'last_time': ts1}})
(3)加入用户扫码登录之后申请试用填写表单,则表单的重要信息也要更新到user表中
# 根据用户唯一ID存啊,记得表单提交时带着user_id隐藏提交 phone_obj = mongo.db.users.find_one({"user_id": user_id}) if phone_obj: up_obj = mongo.db.users.update({'user_id': user_id}, {'$set': {'contact_info': contact_info,'user_type': CONSUMER}})
(4)小程序的第一次登录,返回openID而不是unionID的时候,要通过前端传过来的jscode以及encryptedData和iv以及session_key解码敏感信息来获得用户user_info以及unionID,这个处理过程和上面的统一处理都写到user表中:
具体代码查看那篇:微信小程序:登录-python处理
五 表中具体信息如下
{ "_id" : ObjectId("5b07c71e0f49405990a5d956"), "user_id" : "013a4759-91f2-4a73-b90b-eaca86d20205”, "user_type" : "consumer”, "consumer_id" : "175f20b6-4048-4bc8-947d-f20c57627f6b”, "create_time" : "2018-05-25 16:19:41”, "last_time" : "2018-06-05 11:58:13” "wechat_info" : { "token_info" : { "openid" : "xxxxx", "scope" : "snsapi_login", "access_token" : “xxxxx", "unionid" : “xxxxxx", "expires_in" : 7200, "refresh_token" : “xxxxx" }, "user_info" : { "province" : "", "openid" : “xxxxx", "headimgurl" : “xxx", "language" : "zh_CN", "city" : "", "country" : "CN", "sex" : 1, "unionid" : “xxxxxx", "privilege" : [ ], "nickname" : "adamanter" } }, "contact_info" : { "username" : "adamanter", "company" : "cc", "phone_num" : “18018881666" }, } { "_id" : ObjectId("5b160a550f4940282d7b8a6f”), "referer" : "https://open.weixin.qq.com/connect/qrconnect?appid=xxx&redirect_uri=https%3a%2f%2fdemo.xxxxx.com%2fapply_scan?type=apply&response_type=code&scope=snsapi_login&state=session123456”, "create_time" : "2018-06-05 11:58:13”, "user_id" : "013a4759-91f2-4a73-b90b-eaca86d20205”, "user_type" : "guest” }