• 微信小程序登录对接Django后端实现JWT方式验证登录


    先上效果图


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

    流程

    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的思路,很多地方不严谨,仅供参考

  • 相关阅读:
    伪元素:placeholder-shown&&:focus-within
    伪元素:target
    伪元素:focus-within
    MpVue解析
    ESLint在vue中的使用
    vue动态 设置类名
    Java 文件流操作.
    SpringMVC 与 REST.
    基于Nginx和Zookeeper实现Dubbo的分布式服务
    基于Spring的RPC通讯模型.
  • 原文地址:https://www.cnblogs.com/PyKK2019/p/10880657.html
Copyright © 2020-2023  润新知