­

微信小程序登錄對接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的思路,很多地方不嚴謹,僅供參考