一。登录接口。

  官方文档https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html

  在登录接口中,有以下步骤:

  1.通过微信函数wx获取code,request到后端。

  2.获取开发者的appid和secret和code传输到开发者url

GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code

https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html

  3.获得openid和session_key自关联到数据库(open随着用户信息保存到数据库,session_key返回到前端保存)

  4。在随后的业务中带上openid获取用户,返回业务数据。

用户视图:

from rest_framework.views import APIView
from rest_framework.response import Response
from django.core.cache import cache
from app01 import models
import hashlib,time
from app01.wx import wx_Login
class Login(APIView):
def post(self,request):
param=request.data
if param.get("code"):
data=wx_Login.login(param.get("code"))
if data:
val=data['openid']+"&"+data["session_key"]
key=str(int(time.time()))+data['openid']
md5=hashlib.md5()
md5.update(key.encode("utf-8"))
key=md5.hexdigest()
cache.set(key,val)
has_user=models.Wxuser.objects.filter(openid=data['openid']).first()
if not has_user:
models.Wxuser.objects.create(openid=data['openid'])
return Response({"code":200,"msg":"ok",'data':{"login_key":key}}) else:
return Response({"code":200,"msg":"code错误"})
else:
return Response({"code": 200, "msg": "缺少参数"})

view/User

import requests
from app01.wx import settings def login(code):
code_url = settings.code2Session.format(settings.AppId, settings.AppSecret, code)
response = requests.get(code_url)
json_response = response.json()
if json_response.get('session_key'):
return json_response
else:
return False

wx/wx_login

AppId=""

AppSecret=""

code2Session="https://api.weixin.qq.com/sns/jscode2session?appid={}&secret={}&js_code={}&grant_type=authorization_code"
pay_mchid =''
pay_apikey = ''

wx/setting

二。授权流程

  在这个授权流程中,session_key是会过期的,所以要通过checksession来判断session是否过期,

  通过getsession和getuserinfo来获取用户当前设置,和用户的信息。

  通过登录的session_key,前端传输的encryptedData,iv,login_key来解密出个人信息

  pip3 install pycryptodome

import base64
import json
from Crypto.Cipher import AES
from . import settings class WXBizDataCrypt:
def __init__(self, appId, sessionKey):
self.appId = appId
self.sessionKey = sessionKey def decrypt(self, encryptedData, iv):
# base64 decode
sessionKey = base64.b64decode(self.sessionKey)
encryptedData = base64.b64decode(encryptedData)
iv = base64.b64decode(iv) cipher = AES.new(sessionKey, AES.MODE_CBC, iv) decrypted = json.loads(self._unpad(cipher.decrypt(encryptedData))) if decrypted['watermark']['appid'] != self.appId:
raise Exception('Invalid Buffer') return decrypted def _unpad(self, s):
return s[:-ord(s[len(s)-1:])] @classmethod
def getInfo(cls,encryptedData,iv,sessionKey):
return cls(settings.AppId, sessionKey).decrypt(encryptedData, iv)

wx/WXBizDataCrypt.py

class getInfo(APIView):
def post(self,request,*args,**kwargs):
param = request.data
print(request.data)
if param['encryptedData'] and param['iv'] and param['login_key']:
print(cache.get(param['login_key']))
openid,session_key = cache.get(param['login_key']).split('&')
data = WXBizDataCrypt.WXBizDataCrypt.getInfo(param['encryptedData'],param['iv'],session_key)
save_data = {
"name": data['nickName'],
"avatar": data['avatarUrl'],
"language": data['language'],
"province": data['province'],
"city": data['city'],
"country": data['country'],
}
models.Wxuser.objects.filter(openid=openid).update(**save_data)
data = models.Wxuser.objects.filter(openid=openid).first()
data = User_ser.User_ser(instance=data,many=False).data
return Response({"code":200,"msg":"成功","data":data})
return Response({"code":200,"msg":"缺少参数"})

views

三。支付流程

  https://developers.weixin.qq.com/miniprogram/dev/api/open-api/payment/wx.requestPayment.html

  在开发文档中的数据

pay:function(){
wx.request({
url: "http://127.0.0.1:8000/pay/",
method: "POST",
data:{"login_key":wx.getStorageSync("login_key")},
header: { "content-type": "application/json" },
success: function (e) {
console.log(e)
wx.requestPayment({
'timeStamp': e.data.data.timeStamp,
'nonceStr': e.data.data.nonceStr,
'package': e.data.data.package,
'signType': e.data.data.signType,
'paySign': e.data.data.paySign,
'success': function (res)
{
console.log(res,"成功")
},
'fail': function (res)
{
console.log("支付失败",res)
}, ```
})
}
})
``` },

前端

 <button bind:tap="pay"> 支付</button>
import hashlib
import random
import time
from django.core.cache import cache from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
# Create your views here.
from .wx import settings
from .wx.wx_login import login as logins
from . import models
from .wx import WXBizDataCrypt
from app01.my_ser import User_ser
import requests class test(APIView):
def post(self,request,*args,**kwargs):
print(request)
return Response(data={'msg':'ok'},status='') class login(APIView):
def post(self,request,*args,**kwargs):
param = request.data
print(param.get('code'))
if param.get('code'):
data = logins(param.get('code'))
if data:
val = data['openid'] + '&' + data['session_key']
print("openid"+data['openid'],"session_key"+ data['session_key'])
key = data['openid'] + str(int(time.time()))
md5 = hashlib.md5()
md5.update(key.encode('utf-8'))
key = md5.hexdigest()
cache.set(key,val)
has_user = models.Wxuser.objects.filter(openid=data['openid']).first()
if not has_user:
models.Wxuser.objects.create(openid=data['openid'])
return Response({
"code": 200,
"msg": "ok",
"data": {"login_key": key}
})
else:
return Response({'code':404,'msg':'code无效'})
else:
return Response({'code':200,'msg':'没有参数'}) class getInfo(APIView):
def post(self,request,*args,**kwargs):
param = request.data
print(request.data)
if param['encryptedData'] and param['iv'] and param['login_key']:
print(cache.get(param['login_key']))
openid,session_key = cache.get(param['login_key']).split('&')
data = WXBizDataCrypt.WXBizDataCrypt.getInfo(param['encryptedData'],param['iv'],session_key)
save_data = {
"name": data['nickName'],
"avatar": data['avatarUrl'],
"language": data['language'],
"province": data['province'],
"city": data['city'],
"country": data['country'],
}
models.Wxuser.objects.filter(openid=openid).update(**save_data)
data = models.Wxuser.objects.filter(openid=openid).first()
data = User_ser.User_ser(instance=data,many=False).data
return Response({"code":200,"msg":"成功","data":data})
return Response({"code":200,"msg":"缺少参数"}) class pay(APIView):
def post(self,request,*args,**kwargs):
param = request.data
if param.get("login_key"):
openid, session_key = cache.get(param.get("login_key")).split("&")
self.openid = openid
if request.META.get('HTTP_X_FORWARDED_FOR'):
self.ip =request.META['HTTP_X_FORWARDED_FOR']
else:
#如果没有用Nginx就用REMOTE_ADDR
self.ip = request.META['REMOTE_ADDR']
data = self.pay()
return Response({"code":200,"msg":"ok","data":data})
else:
return Response({"code": 400, "msg": "缺少参数"}) def get_str(self):
str_all = "1234567890abcdefghijklmnopqrstuvwxyz"
nonce_str = "".join(random.sample(str_all,20))
return nonce_str def xml_to_dict(self,data):
import xml.etree.ElementTree as ET
xml_dict = {}
data_dic = ET.fromstring(data)
for item in data_dic:
xml_dict[item.tag] = item.text
return xml_dict def get_sign(self):
data_dic = {
"nonce_str": self.nonce_str,
"out_trade_no": self.out_trade_no,
"spbill_create_ip": self.ip,
"notify_url": self.notify_url,
"openid": self.openid,
"body": self.body,
"trade_type": "JSAPI",
"appid": self.appid,
"total_fee": self.total_fee,
"mch_id": self.mch_id
}
sign_str = "&".join([f"{k}={data_dic[k]}" for k in sorted(data_dic)])
sign_str = f"{sign_str}&key={settings.pay_apikey}"
md5 = hashlib.md5()
md5.update(sign_str.encode("utf-8"))
return md5.hexdigest().upper() def get_order(self):
order_id = str(time.strftime("%Y%m%d%H%M%S"))
return order_id def pay(self):
self.appid = settings.AppId
self.mch_id = settings.pay_mchid
self.nonce_str = self.get_str()
self.body = "lzx"
self.out_trade_no = self.get_order()
self.total_fee = 1
self.spbill_create_ip = self.ip
self.notify_url = "http:/www.baidu.com"
self.trade_type = "JSAPI"
self.sign = self.get_sign()
data = f'''
<xml>
<appid>{self.appid}</appid>
<body>{ self.body}</body>
<mch_id>{self.mch_id}</mch_id>
<nonce_str>{self.nonce_str}</nonce_str>
<notify_url>{self.notify_url}</notify_url>
<openid>{self.openid}</openid>
<out_trade_no>{self.out_trade_no}</out_trade_no>
<spbill_create_ip>{self.spbill_create_ip}</spbill_create_ip>
<total_fee>{self.total_fee}</total_fee>
<trade_type>{self.trade_type}</trade_type>
<sign>{self.sign}</sign>
</xml>
'''
url = "https://api.mch.weixin.qq.com/pay/unifiedorder"
response = requests.post(url,data.encode("utf-8"),headers={"content-type":"application/xml"})
res_data=self.xml_to_dict(response.content)
data=self.two_sign(res_data["prepay_id"])
return data def two_sign(self, prepay_id):
timeStamp=str(int(time.time()))
nonceStr=self.get_str()
data_dict={
"appId":settings.AppId,
"timeStamp":timeStamp,
"nonceStr":nonceStr,
"package":f"prepay_id={prepay_id}",
"signType":"MD5"
}
sign_str = "&".join([f"{k}={data_dict[k]}" for k in sorted(data_dict)])
sign_str = f"{sign_str}&key={settings.pay_apikey}"
md5 = hashlib.md5()
md5.update(sign_str.encode("utf-8"))
sign=md5.hexdigest().upper()
data_dict["paySign"]=sign
data_dict.pop("appId")
return data_dict

view

  需要二次生成签名,并以xml的方式提交url。还需要payid。

  在django中,可以通过request中的HTTP_X_FORWARDED_FOR,进行获取,用以共给支付接口。

            if request.META.get("HTTP_X_FORWARDED_FOR"):
host_ip = request.META["HTTP_X_FROWARDED_FOR"]

  

requests的使用:

get:

import requests
response = requests.get("http://www.baidu.com/") # 也可以这么写
# response = requests.request("get", "http://www.baidu.com/")

post:

import requests

kw = {'wd':'苍井空'}

headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}

# params 接收一个字典或者字符串的查询参数,字典类型自动转换为url编码,不需要urlencode()
response = requests.get("http://www.baidu.com/s?", params = kw, headers = headers) # 查看响应内容,response.text 返回的是Unicode格式的数据
print response.text # 查看响应内容,response.content返回的字节流数据
print respones.content # 查看完整url地址
print response.url # 查看响应头部字符编码
print response.encoding # 查看响应码
print response.status_code

  其他https://www.cnblogs.com/lowmanisbusy/p/9065359.html

day87_11_7微信小程序之登录,支付(获取ip,requests使用),授权的更多相关文章

  1. php(ThinkPHP)实现微信小程序的登录过程

    源码也在我的github中给出 https://github.com/wulongtao/think-wxminihelper 下面结合thinkPHP框架来实现以下微信小程序的登录流程,这些流程是结 ...

  2. 微信小程序-form表单-获取用户输入文本框的值

    微信小程序-form表单-获取用户输入文本框的值 <input name='formnickname' class="textarea" placeholder=" ...

  3. 使用Shiro+JWT完成的微信小程序的登录(含讲解)

    使用Shiro+JWT完成的微信小程序的登录 源码地址https://github.com/Jirath-Liu/shiro-jwt-wx 微信小程序用户登陆,完整流程可参考下面官方地址,本例中是按此 ...

  4. 解决微信小程序中Date.parse()获取时间戳IOS不兼容的问题(IOS为NaN的问题)

    前端同事在做微信小程序时发现IOS获取的时间戳为空的问题,后来通过跟踪发现,原来是因为IOS系统不支持2017-01-01格式的时间导致的, var mydata = '2017-01-01 11:0 ...

  5. 微信小程序维护登录态与获取用户信息

    前言. 微信小程序的运行环境不是在浏览器下运行的.所以不能以cookie来维护登录态.下面我就来说说我根据官方给出的方法来写出的维护登录态的方法吧. 一.登录态维护 官方的文档地址:https://m ...

  6. 让你的微信小程序具有在线支付功能

    前言 最近需要在微信小程序中用到在线支付功能,于是看了一下官方的文档,发现要在小程序里实现微信支付还是很方便的,如果你以前开发过服务号下的微信支付,那么你会发现其实小程序里的微信支付和服务号里的开发过 ...

  7. 微信小程序之登录态维护(十一)

    [未经作者本人同意,请勿以任何形式转载] >什么是登录态? 所谓登录态,就是程序在运行时,能够识别当前用户,能够证明自己的唯一性且合法. 我们知道,WEB服务器通过浏览器携带的cookie获取s ...

  8. 微信小程序:java后台获取openId

    一.功能描述 openId是某个微信账户对应某个小程序或者公众号的唯一标识,但openId必须经过后台解密才能获取(之前实现过前台解密,可是由于微信小程序的种种限制,前台解密无法在小程序发布后使用) ...

  9. 使用uni-app开发微信小程序之登录模块

    从微信小程序官方发布的公告中我们可获知:小程序体验版.开发版调用 wx.getUserInfo 接口,将无法弹出授权询问框,默认调用失败,需使用 <button open-type=" ...

随机推荐

  1. python中错误、调试、单元测试、文档测试

    错误分为程序的错误和由用户错误的输入引起的错误,此外还有因为各种各样意外的情况导致的错误,比如在磁盘满的时候写入.从网络爬取东西的时候,网络断了.这类错误称为异常 错误处理 普通的错误处理机制就是在出 ...

  2. JavaScript banner轮播 左右切换 圆点点击切换

    1.效果如下图: 2.源码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charse ...

  3. sql server数据库查询取出重复数据记录

    问题:博主在2011年6月,广东技术师范大学大四的时候,从学校计算机科学学院网站看到招聘信息并到广东中原地产IT部面试,很清楚记得当时的面试题目:怎么从数据库里面查询重复记录. 解决方案:在sql s ...

  4. s3c2440裸机-清bss原理及实现

    1.清bss的引入(为什么要清bss) 我们先举个例子: #include "s3c2440_soc.h" #include "uart.h" char g_C ...

  5. Linux系统学习 十八、VSFTP服务—虚拟用户访问—配置虚拟用户访问

    配置虚拟用户访问 首先至少要关闭userlist 改完配置文件是要重启服务来使它生效 其实在刚装好vsftp的时候的配置文件不用修改的情况下配置虚拟用户访问控制是最好的 local_root选项不影响 ...

  6. 生成对抗性网络GAN

    同VAE模型类似,GAN模型也包含了一对子模型.GAN的名字中包含一个对抗的概念,为了体现对抗这个概念,除了生成模型,其中还有另外一个模型帮助生成模型更好地学习观测数据的条件分布.这个模型可以称作判别 ...

  7. 14. Go 语言编译与工具

    Go 语言编译与工具 Go 语言的工具链非常丰富,从获取源码.编译.文档.测试.性能分析,到源码格式化.源码提示.重构工具等应有尽有. 在 Go 语言中可以使用测试框架编写单元测试,使用统一的命令行即 ...

  8. TKinter当Label绑定bind事件时传参方法

    记录下tkinter的 当在label绑定bind事件时,遇到需要传参时的解决方法(因为有event存在 所以不能直接传参) https://www.cnblogs.com/liyuanhong/ar ...

  9. [译]Vulkan教程(18)命令buffers

    [译]Vulkan教程(18)命令buffers Command buffers 命令buffer Commands in Vulkan, like drawing operations and me ...

  10. Shape.Type属性名称及对应值列表

    在Excel工作表中,有多种Shape类型的时候,可以通过shape.Type属性值返回一个代表形状类型的MsoShapeType数值.通过该数值可知该图形的类型! 列表如下: 名称 值 说明 mso ...