微信小程序登录对接Django后端实现J

  • 2020 年 1 月 16 日
  • 笔记

先上效果图

点击授权按钮后可以显示部分资料和头像,点击修改资料可以修改部分资料。

流程

1.使用微信小程序登录和获取用户信息Api接口 2.把Api获取的用户资料和code发送给django后端 3.通过微信接口把code换取成openid 4.后端将openid作为用户名和密码 5.后端通过JSON web token方式登录,把token和用户id传回小程序 6.小程序将token和用户id保存在storage中 下次请求需要验证用户身份的页面时,在header中加入token这个字段

微信小程序代码

获取用户信息的方法这里不展示,可以在微信小程序文档中看到 登录方法

  login: function(event) {      wx.login({        success: res => {          console.log(res)          //请求后端换取openid的接口          http.request({            url: '/get-openid/',            method: 'POST',            data: {            //将code传到后端              jscode: res.code            },            success: res => {              //获取到openid作为账号密码              console.log(res)              console.log(app.globalData.userInfo)              http.request({                url: '/wx-login/',                method: 'POST',                data: {                  openid: res.openid,                  session_key: res.session_key,                  nickname: app.globalData.userInfo.nickName,                  avatar_url: app.globalData.userInfo.avatarUrl,                  gender: app.globalData.userInfo.gender                },                //登录成功后返回token保存在storage中                success: res => {                  console.log(res)                  //token存入storage                  wx.setStorageSync('jwt_token', res.token)                  wx.setStorageSync('user_id', res.user_id)                  this.reFreshUserProfile()                  //登录状态置为true                  this.setData({                    isLogin: true,                    hasUserInfo: true                  })                  app.globalData.isLogin = true                }              })              }          })        }      })    }

注销方法

  logout: function(res) {      this.setData({        isLogin:false,        hasUserInfo:false      })      app.globalData.isLogin = false      wx.removeStorageSync('jwt_token')      wx.removeStorageSync('user_id')    },

Django后端的实现

首先安装djangorestframework-jwt 这里不使用他默认的登录接口,如下所示

它提供了手动签发token和解密token的功能,因此最好自己实现 手动签发token

    jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER      jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER      payload = jwt_payload_handler(user)      token = jwt_encode_handler(payload)

手动解密token

    jwt_decode_handler = api_settings.JWT_DECODE_HANDLER      user_dict = jwt_decode_handler(token)      user_id = user_dict['user_id']

后端换取openid

class OpenId:      def __init__(self, jscode):          self.url = 'https://api.weixin.qq.com/sns/jscode2session'          self.app_id = env.str('APPID')          self.app_secret = env.str('APPSECRET')          self.jscode = jscode        def get_openid(self):          url = self.url + "?appid=" + self.app_id + "&secret=" + self.app_secret + "&js_code=" + self.jscode + "&grant_type=authorization_code"          res = requests.get(url)          try:              openid = res.json()['openid']              session_key = res.json()['session_key']          except KeyError:              return 'fail'          else:              return openid, session_key

后端返回openid接口实现

这里只使用简单的FBV视图 注:前端传来的值无法从request.POST中接收到,只能使用如下方法

@require_http_methods(['POST'])  @csrf_exempt  def GetOpenIdView(request):      data = json.loads(request.body)      jscode = data['jscode']        openid, session_key = OpenId(jscode).get_openid()      return JsonResponse({          'openid': openid,          'session_key': session_key      })

后端登录接口实现

如果不存在用户则自动创建 为了简单,用户名和密码都是openid

@require_http_methods(['POST'])  @csrf_exempt  def login_or_create_account(request):      data = json.loads(request.body)      print(data)      openid = data['openid']      nickname = data['nickname']      avatar_url = data['avatar_url']      gender = data['gender']        try:          user = User.objects.get(username=openid)      except User.DoesNotExist:          user = None        if user:          user = User.objects.get(username=openid)      else:          user = User.objects.create(              username=openid,              password=openid,              nickname=nickname,              avatar_url=avatar_url,              gender=gender          )        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER      jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER      payload = jwt_payload_handler(user)      token = jwt_encode_handler(payload)      res = {          'status': 'success',          'nickname': user.nickname,          'user_id': user.id,          'token': token      }      return JsonResponse(res)

以上就是简单的微信小程序登录对接Django的思路,很多地方不严谨,仅供参考