Django实现微信商城小程序后端(一) 微信登录

话不多说,直接开始,大概流程如下
1、小程序通过wx.login请求获取用户的code,发送给后端
2、后端通过code换取用户登录凭证,也就是openid
3、后端判断数据库是否存在该用户,不存在,则创建,然后返回token;存在,则直接创建token返回给前端。

微信请求代码块

代码块没有做封装
```
   var host = 'http://localhost:8000/user/login'
  // 登录
  wx.login({
    success: res => {
      wx.request({
        url: host,
        method: 'post',
        data: res,
        success (res) {
          if (res.data.status){
            wx.setStorageSync('token', res.data.data.token)
          }
        }
      })
      console.log(res)
      // 发送 res.code 到后台换取 openId, sessionKey, unionId
    }
  })
```

model

from django.db import models

# Create your models here.

class WeChatUser(models.Model):
	#uuid存储用户的openid
    uuid = models.CharField(max_length=32, verbose_name='用户唯一识别码',null=True)
    username = models.CharField(max_length=32, verbose_name='用户昵称',null=True)
    grade = models.CharField(max_length=8,verbose_name='性别',null=True)
    city = models.CharField(max_length=32, verbose_name='城市',null=True)
    province = models.CharField(max_length=32, verbose_name='省份',null=True)
    create_time = models.DateTimeField(auto_now_add=True)
    update_time = models.DateTimeField(auto_now=True)
    id_delete = models.BooleanField(default=False)

    class Meta:
        verbose_name = '用户信息表'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.username

view

from django.shortcuts import render, HttpResponse
from rest_framework.views import APIView
from rest_framework import viewsets
from .util import info, JwtToken
# Create your views here.
import requests
from .models import WeChatUser

APPID = '填自己的'
SECRET = '填自己的'

class UserAuth(APIView):
	
    def post(self, request):
        data = request.data
        # 获取前端传过来的code
        JSCODE = data.get('code')
        if JSCODE:
            try:
                # 换取微信登录凭证
                wx_url = 'https://api.weixin.qq.com/sns/jscode2session?appid={}&secret={}&js_code={}&grant_type=authorization_code'.format(
                    APPID, SECRET, JSCODE)
                wx_res = requests.get(wx_url).json()
            except Exception as e:
                return info(status=0, message=str(e))

            try:
                # 查询数据库是否有该用户
                ent = WeChatUser.objects.filter(uuid=wx_res['openid']).exists()
                # 判断没有该用户则创建该用户
                if not ent:
                    WeChatUser(uuid=wx_res['openid']).save()
                # 初始化jwt_token
                token_obj = JwtToken()
                token = token_obj.encode_token({'uuid': wx_res['openid']})
                # 返回给用户
                return info(data={'token': token})
            except:
                return info(status=0, message='服务器内部错误')
        return info(status=0, message='未获取到code')

util.py

from uuid import uuid4
import hashlib
import time
import os
from rest_framework.response import Response
from jwt import JWT, jwk_from_dict, jwk_from_pem
from datetime import datetime, timedelta, timezone
from jwt.utils import get_int_from_datetime

#pub_key、pri_key使用下面这个网址生成,然后直接粘贴进来就ok了
#https://mkjwk.org/?spm=a2c4g.11186623.2.20.2aed167chumlVx

# 根据用户传递的值用私钥加密,签名,公钥解密、解签
class JwtToken:
    pub_key = {自己生成 }
    pri_key = { 自己生成}

    def encode_token(self, data, set_time=240):
        # with open("./pri.pem", 'rb') as f:
        #     jwk_from_pem(f.read())
        signing_key = jwk_from_dict(self.pri_key)
        instance = JWT()
        # print(signing_key.to_dict())
        data['iat'] = get_int_from_datetime(datetime.now(timezone.utc))
        data['exp'] = get_int_from_datetime(datetime.now(timezone.utc) + timedelta(hours=set_time))
        # print(data)
        return instance.encode(payload=data, key=signing_key, alg='RS256')

    def decode_token(self, data):
        verifying_key = jwk_from_dict(self.pub_key)
        instance = JWT()
        return instance.decode(data, verifying_key, do_time_check=True)

# 哈希密码
def pwd_hash(val):
    slat = 'zheshiyan'
    md5 = hashlib.md5()

    # print(val, slat)
    md5.update((val+slat).encode('utf-8'))
    return md5.hexdigest()

#重写返回值格式
def info(data='', status=1, message='', headers=None):
    res = Response()
    res.data = {
        'status': status,
        'message': message,
        'data': data
    }
    if headers:
        for k, v in headers.items():
            res[k] = v
    return res

这个登录没有写serializers,大概就是这样实现。

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值