03-04 微信登入小程序与后端实现
______egon新书python全套来袭请看:https://egonlin.com/book.html
微信登入小程序与后端实现
需求:实现小程序端实现登入以后,后端实现登入状态
小程序端
app.js
App({
onLaunch: function () {
// 展示本地存储能力001bHJ281qo7rS1JR1481OQC281bHJ2B
var _this = this;
wx.login({
success: res => {
// console.log(res);
wx.request({
url: _this.globalData.apiDomain +'/api/member/code/login',
data: {
code: res.code
},
method: "POST",
header: {
'content-type': 'application/json' // 默认值
},
success: function (res) {
console.log(res);
wx.setStorageSync('login_key', res.data.data.login_key);
},
fail:function(res){
console.log(res)
}
})
}
});
},
//设置全局的变量,apiDomain这是我们接口的ip
globalData: {
apiDomain:'http://127.0.0.1:8000',
//保存登入的标识
login_key:''
}
})
服务端
1添加登入路由user.login.as_view(),接收小程序中传过来的code。
2 我们通过code请求微信接口获取session_key和用户唯一标识openid,当我们拿到openid后,保存至Wxuser表
3 我们随机生成一个login_key,作为键,将session_key和openid拼接,作为值,保存到redis,在将login_key(相当于web中的session)返回小程序,后面小程序需要登入请求的接口,必须带login_key,作为用户标识
url.py
from django.contrib import admin
from django.urls import path
from django.conf.urls import url
from api.views import product,user
urlpatterns = [
path('admin/', admin.site.urls),
url(r'^api/indexlist/categoryList$', product.caetgoryList.as_view()),
url(r'^api/indexlist/IndexProductList$', product.ProductList.as_view()),
url(r'^api/indexlist/categoryProductsList$', product.categoryProductsList.as_view()),
url(r'^api/indexlist/detailProduct$', product.detailProduct.as_view()),
url(r'^api/member/code/login$', user.login.as_view()),
]
user.py
from django.shortcuts import render,HttpResponse
from rest_framework.views import APIView
from api.wx import wxlogin,UserInfo,setting
from api import baseResponse
import time
from django.core.cache import cache #引入缓存模块
from api import models
from django.http import JsonResponse
import hashlib
# Create your views here.
class login(APIView):
def post(self,request):
# 用apiview之后,再取数据,从request.data
params=request.data
#判断前端是否传入code参数
if params.get('code'):
code=params['code']
#调用wxloing.getLoginInfo获取session_key和openid
user_data=wxlogin.getLoginInfo(code)
if user_data:
#将session_key和openid拼接成字符串,不要乱选拼接字符串,因为openid中有特殊符号
val=user_data['session_key']+'&'+user_data['openid']
#生成MD5值获取key
md=hashlib.md5()
md.update(code.encode('utf-8'))
md.update(str(time.clock()).encode('utf-8'))
key = md.hexdigest()
data={}
try:
#将key和上面的val存入redis
cache.set(key,val)
#返回login_key到小程序
data['login_key'] = key
#将用户数据存入数据库
try:
user = models.Wxuser.objects.get(openid=user_data['openid'])
except Exception as e:
user=None
#如果数据没有则创建记录
if not user:
models.Wxuser.objects.create(openid=user_data['openid'])
re_data = baseResponse.resdic("success", "成功",data )
return JsonResponse(re_data)
except Exception as e:
print(e)
re_data = baseResponse.resdic("error", "redis程序出错" )
return JsonResponse(re_data)
else:
re_data = baseResponse.resdic("error", "获取session_key失败")
return JsonResponse(re_data)
else:
re_data = baseResponse.resdic("error", "缺少参数")
return JsonResponse(re_data)
api.wx.setting.py
AppId="wxd1eba74200bc40c8"
AppSecret="0d7168052febae147f1d70eb6b8996d5"
code2session_url= "https://api.weixin.qq.com/sns/jscode2session?appid={}&secret={}&js_code={}&grant_type=authorization_code"
acces_url= 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={}&secret={}'
api.wx.wxlogin
from api.wx import setting
import requests
import json
def getLoginInfo(code):
url=setting.code2session_url.format(setting.AppId,setting.AppSecret,code)
re_data= requests.get(url)
json_response = re_data.content.decode() # 获取r的文本 就是一个json字符串
# 将json字符串转换成dic字典对象
data = json.loads(json_response)
if data.get('session_key'):
return data
return False