微信小程序注册登录获取用户信息thinkPHP5

需求 :小程序使用微信登录,后端获取用户详细(包含openid,unionid)写入数据库,并生成token

小程序登录获取token

1.通过wx.login获取到code,

2.wx.getUserInfo 获取到加密数据encryptedData ,及iv ,​

3.将数据发送到后台换取token

小程序代码

var that = this;
  wx.getSetting({
    success(res) {
      var status = res.authSetting['scope.userInfo']
      if (status) {
        wx.login({
          success(res) {
            if (res.code) {
              var code = res.code;
              wx.getUserInfo({
                success(res) {
                  wx.showLoading({
                    title: '登陆中',
                    mask: true
                  });
                  that.login(code, res.encryptedData, res.iv)
                }
              })

            }
          }
        })
      }
    }
  })


/**
 * 登录获取token
 */

function login(code, encrypteData, iv) {
  var that = this
  wx.showToast({
    title: '正在登录...',
    icon: 'loading',
    duration: 5000
  });
  wx.request({
    url: url,
    method: 'get',
    data: {
      code: code,
      encrypteData: encrypteData,
      iv: iv
    },
    header: {
      'Content-Type': 'application/json'
    },
    success: function(res) {
    if (res.data.code == 0) {
        that.globalData.token = res.data.data
        wx.hideLoading()
      } else
        console.error(res);
    },
    fail: function() {
      wx.showToast({
        title: '网络错误!',
        duration: 2000
      })
    },
    complete: function() {
 
    }
  })

服务端注册

1.用前端提交的token请求微信服务器获取session_key,

2.用session_key,iv将加密数据进行解密得到用户信息

3.判断是否注册过,写入数据库

4.生成token

代码

/**
     * Notes:登录并注册
     * @auther: xxf
     * Date: 2019/9/29
     * Time: 14:22
     * @param Request $request
     * @return \think\response\Json
     */
    public function login(Request $request)
    {
        $code = $request->post('code');
        $encryptedData = $this->request->post('encryptedData');
        $iv = $this->request->post('iv');
        $model  = new User();
        $res = $model->userLogin($code,$iv,$encryptedData);
        return json($res);
    }
    public function userLogin($code,$iv,$encrypteData)
    {
        try {
            $url = "https://api.weixin.qq.com/sns/jscode2session?appid=$this->appId&secret=$this->appSecret&js_code=$code&grant_type=authorization_code";
            $tokenValue = $this->httpGet($url);
            $data = $this->decryptData($this->appId,$tokenValue->session_key,$encrypteData,$iv);
            $user = User::where('openid',$tokenValue->openid)->find();
            if($user instanceof User) {
                $user->lasttime = time();
                $user->head = $data['avatarUrl'];
                $user->save();
                $mid = $user->id;
            }else{

                $userData = array([
                    'openid' => $data['openId'],
                    'name' => $data['nickName'],
                    'head' => $data['avatarUrl'],
                    'sex' => $data['gender'],
                    'address' => $data['country'].$data['province'].$data['city'],
                    'addtime' => time(),
                    'lasttime' => time(),
                ]);
                $mid = $this->insertGetId($userData);
            }
            if ($mid)
            {
                $jwtToken = new Token();
                $tokenData = array(
                    'mid' => $mid,
                );
                $token = $jwtToken->createToken($tokenData, 86400)['token'];
                return ['data' => $token, 'code' => 0, 'msg' => 'success'];
            } else
                return ['data' => '', 'code' => 1, 'msg' => '异常'];
        } catch (\Exception $e)
        {
            return ['data' => '', 'code' => 1, 'msg' => $e->getMessage()];
        }


    }

 /**
     * Notes:数据解密
     * @auther: xxf
     * Date: 2019/9/29
     * Time: 15:44
     * @param $appId
     * @param $session_key
     * @param $encryptedData
     * @param $iv
     * @return mixed|string
     * @throws \Exception
     */
    private function decryptData( $appId,$session_key,$encryptedData, $iv)
    {
        if (strlen($session_key) != 24 || strlen($iv) != 24) {
            throw new \Exception("encodingAesKey或iv 非法");
        }
        $aesKey=base64_decode($session_key);
        $aesIV=base64_decode($iv);
        $aesCipher=base64_decode($encryptedData);
        $result=openssl_decrypt( $aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV);
        $dataObj=json_decode( $result );
        $result = json_decode($result,true);
        if( $dataObj  == NULL )
            throw new \Exception("解密失败");
        if( $dataObj->watermark->appid != $appId )
            throw new \Exception("解密失败");

        return $result;
    }

private function httpGet($url) {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_TIMEOUT, 500);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_URL, $url);
        $res = curl_exec($curl);
        curl_close($curl);
        return json_decode($res);
    }


其他业务鉴权验证token

小程序后续请求时,在header里携带token

wx.request({
    url: _api,
    header: {
      'content-type': 'application/json',
      'Authorization': token
    },
    method: 'POST',
    data: data,
    success: function (res) {
      if(res.statusCode == 401)
      {
        wx.showToast({
          title: '未登录',
          image: "/assets/icon/icon-warning.png",
        });
      }
      success(res);
    }
  });

后台中间件代码 

    public function handle($request, \Closure $next)
    {
        $token = $request->header('AUTHORIZATION');
        $jwtToken = new Token();
        $checkToken = $jwtToken->checkToken($token);
        $data = (array)$checkToken['data']['data'];
        $mid = $data['mid'] ?? 0 ;
        $user = User::where('id',$mid)->find();
        if($user instanceof User){
            $request->user = $user;
            return $next($request);
        }else{
            $res = [
                'data' => '',
                'code'=>1,
                'msg'=>'未登录'
            ];
            sendResponse($res, 401, 'Unauthorized');
        }
    }

 

有关token生成请参看我的其他博客

发布了85 篇原创文章 · 获赞 45 · 访问量 95万+

猜你喜欢

转载自blog.csdn.net/flysnownet/article/details/101769873