通过微信OAuth2的code参数,初始化用户

@param Request $req
@return array|bool|\Wei\Response
963604
protected function initUserByWechatOAuth2Code(Request $req)
    {
        // 1. 获取OAuth请求的code
        $code = $this->getOAuthCode();
        if (!$code) {
            return false;
        }

        // 2. 通过OAuth2.0的code,获取用户OpenID
        // TODO 允许失败不告警,重试完仍然失败才告警
        $api = wei()->wechatAccount->getCurrentAccount()->createApiService();
        $ret = $api->getOAuth2AccessTokenByAuth(['code' => $req['code']]);

        // 3. 如果错误是invalid code,且还有重试次数,重新跳转获得新的code
        if ($ret['errcode'] == 40029 && $retries = $this->getRetries()) {
            $url = $this->getRedirectUrl(['wechatRetries' => $retries - 1]);

            return $this->response->redirect($url);
        }

        // 4. 重试后还是失败,返回提醒给用户
        if (!isset($ret['openid'])) {
            return $this->ret->err('很抱歉,微信授权失败,请返回再试');
        }

        // 5. 重试成功,做个日志记录
        if (isset($ret['openid']) && isset($req['wechatRetries'])) {
            $this->logger->warning('微信获取Code重试成功', [
                'leftWechatRetries' => $this->getRetries(),
            ]);
        }

        // 6. 获取OpenID成功,创建或获取用户,并设置登录态
        wei()->curUser->loginBy(['wechatOpenId' => $ret['openid']]);
        $this->session->set([
            'accessToken' => $ret['access_token'], // 用于微信地址
            'scope' => $ret['scope'],
            'code' => $req['code'],
            'state' => $req['state'],
        ]);
    }
710238
private function getUserSession(Request $req)
    {
        // check for a session hijacking attempt via the stored user agent
        $session = $this->getSession();
        if ($session->get(self::SESSION_USER_AGENT_KEY) !== $req->agent()) {
            return false;
        }

        $userId = $session->get(self::SESSION_USER_ID_KEY);
        if ($userId === null) {
            return false;
        }

        // if this is a guest user then just return it now
        $userClass = $this->auth->getUserClass();
        if ($userId <= 0) {
            return new $userClass($userId);
        }

        // look up the registered user
        $user = $userClass::where('id', $userId)->first();
        if (!$user) {
            return false;
        }

        // refresh the active session
        if ($session->isStarted()) {
            // check if the session valid
            $sid = $session->getId();
            if (!$this->sessionIsValid($sid)) {
                return false;
            }

            $this->refreshSession($sid);
        }

        // check if the user is 2FA verified
        if ($session->get(self::SESSION_2FA_VERIFIED_KEY)) {
            $user->markTwoFactorVerified();
        }

        return $user->markSignedIn();
    }
93162
public function execute($request)
    {
        RequestNotSupportedException::assertSupports($this, $request);

        $details = ArrayObject::ensureArrayObject($request->getModel());

        if (isset($details['ErrorMessage']) === true) {
            $request->markFailed();

            return;
        }

        if (isset($details['ResCode']) === true) {
            if ($details['ResCode'] === '0') {
                $request->markFailed();

                return;
            }

            $request->markCaptured();

            return;
        }

        if (isset($details['RtnCode']) === true) {
            if ($details['RtnCode'] === '0') {
                $request->markFailed();

                return;
            }

            if ($details['RtnCode'] === '1') {
                if (isset($details['RtnMerchantTradeNo']) === true) {
                    $request->markRefunded();

                    return;
                }
                // 取消訂單(統一超商C2C).
                if (isset($details['CVSPaymentNo']) === true && isset($details['MerchantTradeDate']) === false) {
                    $request->markCanceled();

                    return;
                }

                // 宅配逆物流訂單產生
                if (isset($details['AllPayLogisticsID']) === true && isset($details['MerchantTradeDate']) === false) {
                    $request->markRefunded();

                    return;
                }

                $request->markCaptured();

                return;
            }

            $request->markUnknown();

            return;
        }

        // 超商取貨逆物流訂單(全家超商B2C).
        if (isset($details['RtnMerchantTradeNo']) === true && isset($details['RtnOrderNo']) === true) {
            $request->markRefunded();

            return;
        }

        if (isset($details['CVSStoreID']) === true) {
            $request->markCaptured();

            return;
        }

        $request->markNew();
    }
1057685
public function post(Request $request)
    {
        $id    = $request->attributes->get('id');
        $token = Arr::get($this->getContentAsArray($request), 'token');

        if (! $token) {
            return $this->createSimpleResponse(422, 'Token not specified.');
        }

        $conditions = [
            'user_id'       => $id,
            'token'         => $token,
            'token_type_id' => TokenEntity::TYPE_VERIFY_REGISTRATION,
        ];

        $token = $this->userService->findTokenBy($conditions);

        if (! $token) {
            return $this->createNotFoundResponse();
        }

        try {
            $user = $this->userService->verifyRegistration($token);
        } catch (OutOfBoundsException $e) {
            $httpCodes = [
                UserService::INCORRECT_TOKEN_TYPE => 422,
                UserService::TOKEN_EXPIRED        => 410,
                UserService::TOKEN_NOT_FOUND      => 404,
            ];

            return $this->createErrorResponse(
                ['token' => ['INVALID']],
                $httpCodes[$e->getCode()]
            );
        }

        $user = $user->getArrayCopy();

        unset($user['password']);

        return $user;
    }
926235
public function getClientAction(Request $request)
    {
        if (!$this->getAuthenticator()->isAuthenticated() && null !== $request->query->get('nolog')) {
            return $this->app->redirectPath('login_authenticate_as_guest', ['redirect' => 'client']);
        }
        if (null !== $response = $this->getFirewall()->requireAuthentication()) {
            return $response;
        }

        $this->getSession()->getFlashBag()->add('step_by_step', '');

        return $this->app->redirect($this->app->path('prod', array('client')));
    }
366191
public function verifyRedirect($request)
    {
        if(empty($request)) {//判断请求的参数是否为空
            return false;
        }

        //生成签名结果
        $data['prestr'] = Helper::buildRequestPreStr($request);
        $data['sign'] = $request['sign'];
        $isSign = $this->sign->verifySign($data, trim($this->config[$this->signKeyConfigName]));

        return $isSign;
    }
642415
public function getSerializer(Request $req)
    {
        $modelSerializer = new ModelSerializer($req);
        $jsonSerializer = new JsonSerializer($req);

        $serializer = new ChainedSerializer();
        $serializer->add($modelSerializer)
                   ->add($jsonSerializer);

        return $serializer;
    }
1246997
public function verifyRequest(Request $request = null)
    {
        $request = $request ?: $this->request;
        $response = $request->request->get('g-recaptcha-response');
        $remoteip = $request->getClientIp();

        return $this->verify($response, $remoteip);
    }
1218181
public function resetAction($req)
    {
        $this->page->setTitle('重置密码');
        $ret = wei()->userVerify->verify($req, false);
        if ($ret['code'] < 0) {
            return $this->err($ret['message']);
        }

        $userId = wei()->e($req['userId']);
        $nonce = wei()->e($req['nonce']);
        $timestamp = wei()->e($req['timestamp']);
        $sign = wei()->e($req['sign']);

        return get_defined_vars();
    }
709549
public function updateAction($req)
    {
        $shop = wei()->shop()->findId($req['id']);

        $ret = $shop->create($req);

        return $ret;
    }
845974
public function supportRequestToken(Request $request)
    {
        $client = $request->getUser() && $request->getPassword();
        $token = 'refresh_token' == $request->get('grant_type') && $request->get('refresh_token');

        return $client && $token;
    }
1331649
public function dispatch(\sb\JSON\RPC2\Request $request)
    {

        if (!(is_array($request->params) || is_object($request->params))) {
            $response = new \sb\JSON\RPC2\Response();
            $response->error = new \sb\JSON\RPC2\Error('-32602');
            $response->message = 'Invalid params';
            $response->error->data = 'Invalid method parameters: ' . json_encode($request->params);
            return $response;
        }

        $host = $this->host;
        $port = $this->port;
        $timeout = $this->timeout;
        $request_timeout = $this->request_timeout;
        $uri = $this->uri;

        $json = json_encode($request);

        $this->logRequest($json);

        if ($this->debug == true) {
            echo "--> " . $json;
        }

        $headers = [];
        
        if ($this->php_serialize_response) {
            $headers[] = "php-serialize-response:".($this->php_serialize_response ? 1 : 0);
        }

        //if there are cookies add them
        if (!empty($this->cookies)) {
            $cookies = '';
            foreach ($this->cookies as $key => $val) {
                $cookies .= $key . '=' . urlencode($val) . ';';
            }

            $headers[] = "Cookie: " . $cookies;
        }

        $response_str = '';

        $ch = curl_init();
        if($headers){
            curl_setopt($ch,CURLOPT_HTTPHEADER, $headers); 
        }
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $this->verify_ssl ? 2 : false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $this->verify_ssl ? 2 : false);
        curl_setopt($ch, CURLOPT_USERAGENT, $this->agent ? $this->agent : \sb\Gateway::$http_host.' '.'\sb\JSON\RPC2\Client ');
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); 
        curl_setopt($ch, CURLOPT_TIMEOUT, $request_timeout); 
        curl_setopt($ch, CURLOPT_PORT, $port);
        
        $url = 'http'.($this->port == 443 ? 's' : '').'://'.$this->host.$uri;
        if($this->method == 'post'){
            if (isset($this->encryption_key)) {
                $json = $this->encryptor->encrypt($json);
            }
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
        } else {
            
            $params = base64_encode(json_encode($request->params));
            $params = urlencode($params);

            $url .= (strstr($this->uri, '?') ? '&' : '?')
                . 'method=' . $request->method . '&params='
                . $params . '&id=' . $request->id;
    
        }
        
        curl_setopt ($ch, CURLOPT_URL, $url);  
       
        $response_str = curl_exec($ch);
        $error = curl_errno($ch);
        if($error){
            $response = new \sb\JSON\RPC2\Response();
            $response->error = new \sb\JSON\RPC2\Error('-32099');
            $response->error->message = 'Server error';
            $response->error->data = 'Could not reach: ' . $this->host . ": #$error - ". curl_error($ch);
            return $response;
        }
        
        return $this->processResponse($response_str);
    }
373111
public function getAuth($code)
    {
        $result = $this->_curl(
            'https://api.weixin.qq.com/sns/oauth2/access_token',
            [
                'appid' => $this->getConfig('appid'),
                'secret' => $this->getConfig('secret'),
                'code' => $code,
                'grant_type' => 'authorization_code',
            ]
        );

        if ($result) {
            return [
                'access_token' => $result['access_token'],
                'openid' => $result['openid'],
            ];
        }

        return false;
    }
1373943
public function syncNewUsersAction($req)
    {
        if ($this->isPhpunit()) {
            return $this->suc('单元测试下,不执行同步');
        }

        // 1. 初始化数据

        // 本次同步成功的用户数
        $syncCount = 0;

        // 本次要同步的用户数
        $num = $req['num'] ?: 30;

        $api = wei()->wechatAccount->getCurrentAccount()->createApiService();

        // 2. 取出待同步的用户
        $syncUsers = wei()->db('wechatSyncUsers')->desc('id')->limit($num)->fetchAll();
        if (!$syncUsers) {
            return $this->suc('同步完成,没有新用户');
        }
        /** @var \Miaoxing\Plugin\Service\User $users */
        $users = wei()->user()->findAll(['id' => wei()->coll->column($syncUsers, 'id')]);

        // 3. 同步用户
        foreach ($users as $user) {
            $ret = wei()->wechatAccount->syncUser($user, $api);
            if ($ret['code'] === 1) {
                ++$syncCount;
            }
            // 删除已同步的记录
            wei()->db->delete('wechatSyncUsers', ['id' => $user['id']]);
        }

        // 4. 返回同步结果
        return $this->suc([
            'total' => $users->length(),
            'syncCount' => $syncCount,
        ]);
    }
1059075
private static function parseRequest($req)
    {
        $rsp = HttpClient::sendRequest($req);

        if ($rsp === false) {
            return array(
                'code'      => Response::COSAPI_NETWORK_ERROR,
                'message'   => 'network error',
            );
        }

        $info = HttpClient::info();
        $ret = json_decode($rsp, true);

        if ($ret === NULL) {
            return array(
                'code'      => Response::COSAPI_NETWORK_ERROR,
                'message'   => $rsp,
                'data'      => array()
            );
        }

        return $ret;
    }
300914
public function exec(array $req = []) {
        usleep(250000);

        // API settings
        $req['apikey'] = $this->apiKeyToken;

        // generate the POST data string
        $postData = http_build_query($req, '', '&');

        // curl handle (initialize if required)
        if (is_null(self::$ch)) {
            self::$ch = curl_init();
            curl_setopt(self::$ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt(
                self::$ch,
                CURLOPT_USERAGENT,
                'Mozilla/4.0 (compatible; Etherscan PHP API; ' . php_uname('a') . '; PHP/' . phpversion() . ')'
            );
        }
        curl_setopt(self::$ch, CURLOPT_URL, \etherscan\api\EtherscanAPIConf::getAPIUrl($this->net));
        curl_setopt(self::$ch, CURLOPT_POSTFIELDS, $postData);
        curl_setopt(self::$ch, CURLOPT_SSL_VERIFYPEER, false);

        // run the query
        $res = curl_exec(self::$ch);
        if ($res === false) {
            throw new \Exception("Curl error: " . curl_error(self::$ch));
        }

        $json = json_decode($res, true);

        // Check for the Etherscan API error
        if (isset($json['error'])) {
            throw new \Exception("Etherscan API error: {$json['error']}");
        }

        return $json;
    }
756468
public function signinAction(Request $request) {
        try {
            $data = $this->getAuthClientIdentifiers($request);

            // exports $client_id, $redirect_uri
            extract($data);

            if(!(($client = $this->clientProvider->getClient($client_id)) && $this->clientProvider->isValid($client, $redirect_uri))) {
                throw new SoauthException(sprintf('No client found with id %s', $client_id));
            }

            $data['client'] = $client;

            $this->info('> Sign in request', ['method' => $request->getMethod(), 'query' => $data]);
            $response = new Response($this->renderer->renderSignInForm($data));
        } catch (BadDataException $e) {
            $this->error('Bad Data Exception: ' . $e->getMessage(), ['errors' => $e->getErrors(), 'exception' => $e]);
            $response = $this->getBadRequestResponse();
        } catch (SoauthException $e) {
            $this->error('Soauth Exception: ' . $e->getMessage(), ['exception' => $e]);
            $response = $this->getBadRequestResponse();
        }

        $this->info('< Response', ['status_code' => $response->getStatusCode()]);
        return $response;
    }