<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                文檔地址: 網站應用的方式進行掃碼登錄:[https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html](https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html) 公眾號的方式進行掃碼登錄:[https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_event_pushes.html](https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_event_pushes.html) 思路: 1:網站應用的方式直接參考微信文檔即可明白登錄流程,詳細調用方法如下: 2:公眾號方式的思路為:通過關注事件進行的推送,即用戶掃描二維碼后微信后臺會向開發者推送關注或已關注的事件消息,開發者通過解析事件消息來對掃碼的用戶進行賬號綁定或者獲取賬號信息,能獲取到賬號信息的即可以登錄,獲取不到則通知用戶進行綁定。詳細調用方法如下: 控制器層: ``` <?php namespace Controllers; use Controllers\BaseController; use Util\SendSms; use \Common\Tools; class OauthController extends BaseController { public function getBindAction() { $auth = $this->request->get('auth'); if (empty($auth)) { $this->outputJsonError('auth參數不允許為空'); } $auth = Tools::authcode($auth, 'DECODE'); if (empty($auth)) { $this->outputJsonError('非法的auth數據'); } $oauthInfo = $this->local->call(array('service' => 'Services\Oauth', 'method' => 'getOauth', 'args' => array(['site' => 2, 'sid' => $auth], "itemid,nickname,userid"))); if (!$oauthInfo['data']) { $this->outputJsonSuccess(['type' => 1]); } elseif ($oauthInfo['data']['userid'] != $this->userinfo['userid']) { $this->outputJsonSuccess(['type' => 2]); } else { $oauthInfo['data']['type'] = 3; $this->outputJsonSuccess($oauthInfo['data']); } } /** * @Author zhp * @DateTime 2020-04-22 * @desc [微信回調通知] * @version [version] * @return [type] [description] */ public function wxchatNotifyAction() { $checkSignature = $this->local->call(array('service' => 'Services\Oauth', 'method' => 'checkSignature', 'args' => array())); if ($checkSignature['code'] != 200) { exit('非法請求'); } $HTTP_RAW_POST_DATA or $HTTP_RAW_POST_DATA = file_get_contents('php://input'); if (!$HTTP_RAW_POST_DATA) { exit($_GET["echostr"]); } $this->local->call(array('service' => 'Services\Oauth', 'method' => 'wxchatNotify', 'args' => array($HTTP_RAW_POST_DATA))); } public function wxchatQrcodeBindAction() { $userid = $this->userinfo['userid']; $sid = Tools::random(9, '123456789'); $auth = Tools::authcode($sid, ''); $scene_str = "wxbind_{$userid}_{$sid}"; $res = $this->local->call(array('service' => 'Services\Oauth', 'method' => 'wxchatQrcode', 'args' => array($scene_str))); if ($res['code'] != 200) { $this->outputJsonError($res['msg']); } else { $this->outputJsonSuccess(['auth' => $auth, 'url' => $res['data']['url']]); } } /** * @Author zhp * @DateTime 2020-04-21 * @desc [公眾號方式-生成二維碼] * @version [version] * @return [type] [description] */ public function wxchatQrcodeAction() { $sid = Tools::random(9, '123456789'); $scene_str = "wxlogin_{$sid}"; $auth = Tools::authcode($sid, ''); $res = $this->local->call(array('service' => 'Services\Oauth', 'method' => 'wxchatQrcode', 'args' => array($scene_str))); if ($res['code'] != 200) { $this->outputJsonError($res['msg']); } else { $this->outputJsonSuccess(['auth' => $auth, 'url' => $res['data']['url']]); } } /** * @Author zhp * @DateTime 2020-04-21 * @desc [公眾號方式-掃碼關注后登錄] * @version [version] * @return [type] [description] */ public function wxchatLoginAction() { $header = []; $auth = $this->request->get('auth'); if (empty($auth)) { $this->outputJsonError('auth參數不允許為空'); } $auth = Tools::authcode($auth, 'DECODE'); if (empty($auth)) { $this->outputJsonError('非法的auth數據'); } $header['HTTP_USER_AGENT'] = $this->request->getHeader("HTTP_USER_AGENT"); $result = $this->local->call(array('service' => 'Services\Oauth', 'method' => 'wxchatLogin', 'args' => array($auth, $header))); $this->outputJsonSuccess($result['data']); } /** * @Author zhp * @DateTime 2020-04-21 * @desc [網站應用方式-掃碼登錄] * @version [version] * @return [type] [description] */ public function wxLoginAction() { $header = []; $code = $this->request->getPost('code'); if (!$code) { $this->outputJsonError('參數不允許為空'); } $header['HTTP_USER_AGENT'] = $this->request->getHeader("HTTP_USER_AGENT"); $result = $this->local->call(array('service' => 'Services\Oauth', 'method' => 'wxLogin', 'args' => array($code, $header))); if ($result['code'] != 200) { $this->outputJsonError($result['msg'], 600, $result['data']); } else { $this->outputJsonSuccess($result['data']); } } /** * @Author zhp * @DateTime 2020-04-21 * @desc [網站應用方式-微信綁定] * @version [version] * @return [type] [description] */ public function wxBindAction() { $code = $this->request->getPost('code'); if (!$code) { $this->outputJsonError('參數不允許為空'); } $wxUser = $this->local->call(array('service' => 'Services\Oauth', 'method' => 'getWx', 'args' => array($code))); if ($wxUser['code'] != 200) { $this->outputJsonError($wxUser['msg']); } $result = $this->local->call(array('service' => 'Services\Oauth', 'method' => 'wxBind', 'args' => array($wxUser['data'], $this->userinfo))); if ($result['code'] != 200) { $this->outputJsonError($result['msg']); } else { $this->outputJsonSuccess($result['data']); } } /** * @Author zhp * @DateTime 2020-04-21 * @desc [微信解綁] * @version [version] * @return [type] [description] */ public function wxDelBingAction() { $this->local->call(array('service' => 'Services\Oauth', 'method' => 'wxDelBind', 'args' => array($this->userinfo))); $this->outputJsonSuccess([]); } public function wxchatDelBindAction() { $data = $this->request->getPost(); if (empty($data['itemid'])) { $this->outputJsonError('參數不允許為空'); } $this->local->call(array('service' => 'Services\Oauth', 'method' => 'editOauth', 'args' => array(['itemid' => $data['itemid'], 'userid' => $this->userinfo['userid']], ['userid' => 0]))); $this->outputJsonSuccess([]); } /** * @Author zhp * @DateTime 2020-04-21 * @desc [網站應用方式or公眾號方式掃碼 后手機號綁定] * @version [version] * @return [type] [description] */ public function wxLoginMobileAction() { $data = $this->request->getPost(); if (empty($data['id']) || empty($data['site']) || empty($data['mobile']) || empty($data['mobilecode'])) { $this->outputJsonError('參數不允許為空'); } if (!Tools::isMobile($data['mobile'])) { $this->outputJsonError('請輸入正確的手機號'); } if (!Tools::isCode($data['mobilecode'])) { $this->outputJsonError('驗證碼格式錯誤'); } if (!in_array($data['site'], [1, 2])) { $this->outputJsonError('site參數錯誤'); } //驗證碼 if ($data['mobilecode'] != $this->memcache->get('bind:mobile:code:' . $data['mobile'])) { $this->outputJsonError('驗證碼錯誤'); } $oauthInfo = $this->local->call(array('service' => 'Services\Oauth', 'method' => 'getOauth', 'args' => array(['itemid' => $data['id']], "itemid"))); if (empty($oauthInfo['data'])) { $this->outputJsonError('不存在該微信用戶信息'); } $oauthInfo = $oauthInfo['data']; $userInfo = $this->local->call(array('service' => 'Services\Member', 'method' => 'get', 'args' => array('mobile', ['mobile' => $data['mobile']]))); if ($userInfo['code'] != 200) { //注冊用戶 $password = Tools::random(8); $result = $this->local->call(array('service' => 'Services\Member', 'method' => 'add', 'args' => array('data' => ['mobile' => $data['mobile'], 'username' => $data['mobile'], 'password' => $password]))); if ($result['code'] != 200) { $this->outputJsonError('注冊失敗'); } $userInfo = $this->local->call(array('service' => 'Services\Member', 'method' => 'get', 'args' => array('id', ['userid' => $result['data']]))); //短信發送密碼 $smsObj = new SendSms(); $smsObj->sendSms($data['mobile'], "您的登錄密碼為{$password},請牢記保存。【星空譯站】"); } else { //檢測用戶是否已綁定 $checkBind = $this->local->call(array('service' => 'Services\Oauth', 'method' => 'getOauth', 'args' => array(['userid' => $userInfo['data']['userid']], "itemid"))); if ($checkBind['data']) { $this->outputJsonError('該手機號已綁定其它微信,請更換手機號'); } } $result = $this->local->call(array('service' => 'Services\Oauth', 'method' => 'wxBind', 'args' => array($oauthInfo, $userInfo['data'], $data['site']))); if ($result['code'] != 200) { $this->outputJsonError($result['msg']); } else { $header['HTTP_USER_AGENT'] = $this->request->getHeader("HTTP_USER_AGENT"); $jwt = $this->local->call(array('service' => 'Services\Oauth', 'method' => 'logAndJwt', 'args' => array($userInfo['data'], $header))); $userInfo['data']['other'] = json_decode($userInfo['data']['other'], true); $this->outputJsonSuccess(['userinfo' => $userInfo['data'], 'jwt' => $jwt['data']['jwt']]); } } } ``` Service邏輯處理層 ``` <?php namespace Services; use Firebase\JWT\JWT; use \Common\ReqHelp; use \Common\Tools; use \Models\Member; use \Models\Oauth; use \Services\BaseService; class OauthService extends BaseService { private $WX_TOKEN_URL = 'https://api.weixin.qq.com/sns/oauth2/access_token'; private $WX_USERINFO_URL = 'https://api.weixin.qq.com/sns/userinfo'; public function wxchatQrcode($scene_str = '') { $access_token = $this->getAccesstoken(); if ($access_token['code'] != 200) { return $this->outputData([], 600, $access_token['msg']); } $url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token={$access_token['data']}"; $param = '{"expire_seconds": 3600, "action_name": "QR_STR_SCENE", "action_info": {"scene": {"scene_str": "' . $scene_str . '"}}}'; $res = ReqHelp::postjson($url, $param); if ($res['0'] != 200) { return $this->outputData([], 600, '二維碼獲取失敗'); } $res = json_decode($res['1'], true); return $this->outputData(['url' => $res['url']]); } public function wxchatNotify($HTTP_RAW_POST_DATA) { $nowtime = time(); if (function_exists('libxml_disable_entity_loader')) { libxml_disable_entity_loader(true); } $x = (array) simplexml_load_string($HTTP_RAW_POST_DATA, 'SimpleXMLElement', LIBXML_NOCDATA); if ($x['MsgType'] == 'event') { //事件 switch ($x['Event']) { case 'CLICK': //點擊菜單拉取消息時的事件推送 switch ($x['EventKey']) { } break; case 'subscribe': //訂閱 $user = $this->getOauth(['openid' => $x['FromUserName']]); $info = $this->wxchatGetWx($x['FromUserName'])['data']; $param = [ 'site' => 2, 'openid' => $x['FromUserName'], 'nickname' => $info['nickname'], 'avatar' => $info['headimgurl'], 'addtime' => $nowtime, 'unionid' => !empty($info['unionid']) ? $info['unionid'] : '', 'subscribe' => 1, 'sex' => $info['sex'], 'city' => $info['city'], 'province' => $info['province'], 'country' => $info['country'], 'language' => $info['language'], ]; if ($user['data']) { $this->editOauth(['itemid' => $user['data']['itemid']], $param); } else { $this->addOauth($param); } if (strpos($x['EventKey'], 'qrscene_') !== false) { $sid = substr($x['EventKey'], 8); if (substr($sid, 0, 7) == 'wxlogin') { $sid = substr($sid, 8); $this->editOauth(['openid' => $x['FromUserName']], ['sid' => $sid]); } if (substr($sid, 0, 6) == 'wxbind') { $sid = explode("_", substr($sid, 7)); $oauthInfo = $this->getOauth(['site' => 2, 'openid' => $x['FromUserName']], "itemid,userid"); if ($oauthInfo['data']['userid']) { $this->editOauth(['openid' => $x['FromUserName']], ['sid' => $sid['1']]); } else { $this->editOauth(['openid' => $x['FromUserName']], ['userid' => $sid['0'], 'sid' => $sid['1']]); } } } break; case 'unsubscribe': //取消訂閱 break; case 'SCAN': //掃描二維碼[已關注] $user = $this->getOauth(['openid' => $x['FromUserName']]); if ($user['data']) { if (substr($x['EventKey'], 0, 7) == 'wxlogin') { $sid = substr($x['EventKey'], 8); $this->editOauth(['openid' => $x['FromUserName']], ['sid' => $sid]); } if (substr($x['EventKey'], 0, 6) == 'wxbind') { $sid = explode("_", substr($x['EventKey'], 7)); $oauthInfo = $this->getOauth(['site' => 2, 'openid' => $x['FromUserName']], "itemid,userid"); if ($oauthInfo['data']['userid']) { $this->editOauth(['openid' => $x['FromUserName']], ['sid' => $sid['1']]); } else { $this->editOauth(['openid' => $x['FromUserName']], ['userid' => $sid['0'], 'sid' => $sid['1']]); } } } break; case 'LOCATION': //上報地理位置事件 break; case 'VIEW': //點擊菜單跳轉鏈接時的事件推送 break; case 'TEMPLATESENDJOBFINISH': //模板消息結果 break; default: break; } } else { //消息 switch ($MsgType) { case 'text': //文本消息 break; case 'image': //圖片消息 break; case 'voice': //語音消息 break; case 'video': //視頻消息 break; case 'location': //地理位置消息 break; case 'link': //鏈接消息 break; default: break; } } return $this->outputData([]); } /** * @Author zhp * @DateTime 2020-04-21 * @desc [解綁微信用戶] * @version [version] * @param [type] $userInfo [description] * @return [type] [description] */ public function wxDelBind($userInfo) { $oauthInfo = Oauth::findFirst(array( 'conditions' => "userid = {$userInfo['userid']}", )); $oauthInfo->delete(); return $this->outputData([]); } public function addOauth($data) { $obj = new Oauth(); if ($obj->save($data)) { return $this->outputData($obj->itemid); } else { return $this->outputData(false, 600, '添加失敗!'); } } public function editOauth($search, $data) { $condition = ''; $bind = []; if ($search) { foreach ($search as $k => $v) { $condition .= "{$k} = :{$k}: and "; $bind[$k] = $v; } } if (empty($condition)) { return $this->outputData([]); } $condition = rtrim($condition, ' and '); $oauthInfo = Oauth::findFirst(array( 'conditions' => $condition, 'bind' => $bind, )); if (!$oauthInfo) { return $this->outputData(false, 600, '不存在該信息'); } $oauthInfo->save($data); return $this->outputData([]); } /** * @Author zhp * @DateTime 2020-04-21 * @desc [獲取綁定信息] * @version [version] * @param [type] $userid [description] * @param string $fields [description] * @return [type] [description] */ public function getOauth($search, $fields = "*") { $condition = ''; $bind = []; if ($search) { foreach ($search as $k => $v) { $condition .= "{$k} = :{$k}: and "; $bind[$k] = $v; } } if (empty($condition)) { return $this->outputData([]); } $condition = rtrim($condition, ' and '); $oauthInfo = Oauth::findFirst(array( 'conditions' => $condition, 'bind' => $bind, 'columns' => "{$fields}", )); if ($oauthInfo) { return $this->outputData($oauthInfo->toArray()); } else { return $this->outputData([]); } } /** * @Author zhp * @DateTime 2020-04-21 * @desc [綁定微信用戶] * @version [version] * @param [type] $wxUser [description] * @param [type] $userInfo [description] * @return [type] [description] */ public function wxBind($wxUser, $userInfo, $site) { //賬戶是否已綁定 $oauthInfo = Oauth::findFirst(array( 'conditions' => "userid = {$userInfo['userid']} and site = {$site}", 'columns' => 'itemid', )); if ($oauthInfo) { return $this->outputData([], 600, '該賬戶已綁定微信'); } //微信是否綁定 $oauthInfo = Oauth::findFirst(array( 'conditions' => "itemid = {$wxUser['itemid']}", )); if (!$oauthInfo) { return $this->outputData([], 600, '不存在該微信信息'); } if ($oauthInfo->userid) { return $this->outputData([], 600, '該微信已綁定賬戶'); } $oauthInfo->save(['userid' => $userInfo['userid']]); return $this->outputData([]); } public function wxchatLogin($sid, $header = []) { $oauthInfo = Oauth::findFirst(array( 'conditions' => "site=2 and sid={$sid}", 'columns' => 'itemid,userid,openid', )); if (!$oauthInfo) { return $this->outputData(['type' => 1], 200, '未關注公眾號'); } $oauthInfo = $oauthInfo->toArray(); if ($oauthInfo['userid']) { //登錄 $userInfo = Member::findFirst(array( "conditions" => "userid = {$oauthInfo['userid']}", ))->toArray(); $userInfo['other'] = json_decode($userInfo['other'], true); $jwt = $this->logAndJwt($userInfo, $header); return $this->outputData(['type' => 3, 'userinfo' => $userInfo, 'jwt' => $jwt['data']['jwt']]); } else { return $this->outputData(['type' => 2, 'id' => $oauthInfo['itemid'], 'site' => 2], 200, '請綁定賬戶'); } } /** * @Author zhp * @DateTime 2020-04-21 * @desc [網站應用方式-掃碼登錄] * @version [version] * @param [type] $code [description] * @param array $header [description] * @return [type] [description] */ public function wxLogin($code, $header = []) { $wxUser = $this->getWx($code); if ($wxUser['code'] != 200) { return $wxUser; } //該微信用戶是否已綁定賬號 $oauthInfo = Oauth::findFirst(array( 'conditions' => "openid = {$wxUser['openid']}", 'columns' => 'userid', )); if ($oauthInfo) { //登錄 $userInfo = Member::findFirst(array( "conditions" => "userid = {$oauthInfo->userid}", ))->toArray(); $jwt = $this->logAndJwt($userInfo, $header); return $this->outputData(['userinfo' => $userInfo, 'jwt' => $jwt['data']['jwt']]); } else { //未登錄手動綁定輸入手機號 $this->di['memcache']->set("wx_login_{$wxUser['openid']}", json_encode($wxUser), 1800); return $this->outputData(['id' => $res['openid'], 'site' => 1], 600, '請綁定賬戶'); } } /** * @Author zhp * @DateTime 2020-04-21 * @desc [網站應用的方式-掃碼登錄-獲取用戶信息] * @version [version] * @param [type] $code [description] * @return [type] [description] */ public function getWx($code) { $appid = $this->di['config']->wx->appid; $secret = $this->di['config']->wx->secret; $url = $this->WX_TOKEN_URL . "?appid={$appid}&secret={$secret}&code=CODE&grant_type=authorization_code"; $res = ReqHelp::get($url); $res = json_decode($res, true); if (!empty($res['errcode'])) { return $this->outputData([], 600, $res['errmsg']); } //獲取微信用戶信息 $url = $this->WX_USERINFO_URL . "?access_token={$res['access_token']}&openid={$res['openid']}"; $wxUser = ReqHelp::get($url); $wxUser = json_decode($wxUser, true); if (!empty($wxUser['errcode'])) { return $this->outputData([], 600, $wxUser['errmsg']); } $wxUser['openid'] = $res['openid']; return $this->outputData(['wxUser' => $wxUser]); } /** * @Author zhp * @DateTime 2020-04-21 * @desc 寫登錄日志和創建jwt * @version [version] * @param [type] $userInfo [description] * @param array $header [description] * @return [type] [description] */ public function logAndJwt($userInfo, $header = []) { $log['userid'] = $userInfo['userid']; $log['username'] = $userInfo['username']; $log['loginip'] = Tools::getip(); $log['agent'] = $header["HTTP_USER_AGENT"] ?? ''; // $result = Tools::getAddressByIp($log['loginip']); // if ($result['status'] == 0) { // $location = $result['data'][0]['location']; // if (strstr($location, ' ')) { // $loca = explode(' ', $location); // $log['location'] = $loca[0] ?? ''; // $log['operator'] = $loca[1] ?? ''; // } else { // $log['location'] = strstr($location, '本地局域網') ? '' : $location; // $log['operator'] = ''; // } // } $this->di['local']->call(array('service' => 'Services\Login', 'method' => 'add', 'args' => array('data' => $log))); //jwt token $jwtdata = [ 'userid' => $userInfo['userid'] ?? 0, 'expire' => strtotime(date('Ymd')) + 97200, //第二天凌晨3點 ]; $jwt = JWT::encode($jwtdata, $this->di['config']->jwt->secret); return $this->outputData(['jwt' => $jwt]); } /** * @Author zhp * @DateTime 2020-04-21 * @desc [公眾號方式-驗證簽名] * @version [version] * @return [type] [description] */ public function checkSignature() { if (empty($_GET["signature"]) || empty($_GET["timestamp"]) || empty($_GET["nonce"])) { return $this->outputData([], 600, '簽名錯誤'); } $signature = $_GET["signature"]; $timestamp = $_GET["timestamp"]; $nonce = $_GET["nonce"]; $token = $this->di['config']->wxPublicChat->token; $tmpArr = array($token, $timestamp, $nonce); sort($tmpArr, SORT_STRING); $tmpStr = implode($tmpArr); $tmpStr = sha1($tmpStr); if ($tmpStr == $signature) { return $this->outputData([]); } else { return $this->outputData([], 600, '簽名錯誤'); } } /** * @Author zhp * @DateTime 2020-04-22 * @desc [公眾號方式-獲取微信用戶信息] * @version [version] * @param [type] $openid [description] * @return [type] [description] */ public function wxchatGetWx($openid) { $access_token = $this->getAccesstoken(); if (!$access_token['data']) { return $this->outputData([], 600, $access_token['msg']); } $url = 'https://api.weixin.qq.com/cgi-bin/user/info?access_token=' . $access_token['data'] . '&openid=' . $openid; $info = json_decode(ReqHelp::get($url), true); return $this->outputData($info); } /** * @Author zhp * @DateTime 2020-04-21 * @desc [公眾號方式] * @version [version] * @return [type] [description] */ public function getAccesstoken() { $appid = $this->di['config']->wxPublicChat->appid; $secret = $this->di['config']->wxPublicChat->secret; $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appid}&secret={$secret}"; $memKey = "{$appid}_accesstoken"; $mem = $this->di['memcache']->get($memKey); if ($mem) { return $this->outputData($mem); } $res = ReqHelp::get($url); $res = json_decode($res, true); if (!empty($res['errcode'])) { return $this->outputData([], 600, $res['errmsg']); } $this->di['memcache']->set($memKey, $res['access_token'], $res['expires_in'] - 1800); return $this->outputData($res['access_token']); } } ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看