微信小程序登陸對接Django後端實現JWT方式驗證登陸

先上效果圖


點擊受權按鈕後能夠顯示部分資料和頭像,點擊修改資料能夠修改部分資料。javascript

流程

1.使用微信小程序登陸和獲取用戶信息Api接口
2.把Api獲取的用戶資料和code發送給django後端
3.經過微信接口把code換取成openid
4.後端將openid做爲用戶名和密碼
5.後端經過JSON web token方式登陸,把token和用戶id傳回小程序
6.小程序將token和用戶id保存在storage中
下次請求須要驗證用戶身份的頁面時,在header中加入token這個字段前端

微信小程序代碼

獲取用戶信息的方法這裏不展現,能夠在微信小程序文檔中看到
登陸方法java

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
              }
            })

          }
        })
      }
    })
  }

註銷方法python

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的功能,所以最好本身實現
手動簽發tokenweb

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)

手動解密tokendjango

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中接收到,只能使用以下方法json

@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的思路,不少地方不嚴謹,僅供參考

相關文章
相關標籤/搜索