1. 程式人生 > 其它 >前端應該如何學習,需要做什麼準備嗎

前端應該如何學習,需要做什麼準備嗎

微信的授權登入和QQ、新浪等平臺的授權登入都大同小異,均採用OauthOAuth2.0鑑權方式。

微信授權分為兩種:

  1. 靜默授權

  2. 彈窗授權,需要使用者手動同意

兩種scope的區別說明:

  1. 以snsapi_base為scope發起的網頁授權,是用來獲取進入頁面的使用者的openid的,並且是靜默授權並自動跳轉到回撥頁的。使用者感知的就是直接進入了回撥頁(往往是業務頁面)

  2. 以snsapi_userinfo為scope發起的網頁授權,是用來獲取使用者的基本資訊的。但這種授權需要使用者手動同意,並且由於使用者同意過,所以無須關注,就可在授權後獲取該使用者的基本資訊。

使用者管理類介面中的“獲取使用者基本資訊介面”,是在使用者和公眾號產生訊息互動或關注後事件推送後,才能根據使用者OpenID來獲取使用者基本資訊。這個介面,包括其他微信介面,都是需要該使用者(即openid)關注了公眾號後,才能呼叫成功的.。

具體而言,網頁授權流程分為四步:

  1. 引導使用者進入授權頁面同意授權,獲取code

  2. 通過code換取網頁授權access_token(與基礎支援中的access_token不同)

  3. 如果需要,開發者可以重新整理網頁授權access_token,避免過期

  4. 通過網頁授權access_token和openid獲取使用者基本資訊(支援UnionID機制)

以下是封裝的微信操作類,需要用到兩個資料表,用於儲存access_token、ticket,由於他們具有一定有效期,且每天請求數有上限,所以開發者需自行儲存

  

<?php
/**
 *   微信操作表
 *   wxtoken 表結構
 *   id
 *   access_token
 *   addtime
 *   wxticket 表結構
 *   id
 *   ticket
 *   addtime
 
*/ class WX { private $appid; private $appserect; private $curl; private $msg; protected $errs = array( '-1' => '系統繁忙,此時請開發者稍候再試', '0' => '請求成功', '40001' => 'AppSecret錯誤或者AppSecret不屬於這個公眾號,請開發者確認AppSecret的正確性', '40002' => '請確保grant_type欄位值為client_credential', '40164' => '呼叫介面的IP地址不在白名單中,請在介面IP白名單中進行設定。', );
function __construct($appid, $appserect) { $this->appid = $appid; $this->appserect = $appserect; $this->curl = new Curl(); } /* 微信網頁授權登入 需要在公眾號設定 - 功能設定 - 網頁授權域名 第一步:使用者同意授權,獲取code scope : snsapi_base 只能獲取openid 直接跳轉 snsapi_userinfo */ public function getCode($redirect_uri, $scope = 'snsapi_userinfo', $state = '1') { $url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={$this->appid}&redirect_uri={$redirect_uri}&response_type=code&scope={$scope}&state={$state}#wechat_redirect"; header("Location:{$url}"); exit; } /* 第二步:通過code換取網頁授權access_token */ public function getAccessTokenByCode($code) { $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={$this->appid}&secret={$this->appserect}&code={$code}&grant_type=authorization_code"; // exit($url); // $curl = new Curl(); $result = $this->curl->doGet($url); if (!$result) { // $this->curl->getError() $this->msg = "獲取token失敗"; return false; } $result = json_decode($result, true); if ($result['errcode']) { $this->msg = $result['errmsg']; return false; } return $result; } // 第三步:重新整理access_token(如果需要) 通過code 獲取openid $type 0靜默授權 1彈窗授權 public function getUserInfo($code, $type = 0, $lang = 'zh_CN ') { $result = $this->getAccessTokenByCode($code); if (!$result) { return false; } $member = C::t(PT_USER)->getByOpenid($result['openid']); if ($member) { return $member; } else { if ($type) { $url = "https://api.weixin.qq.com/sns/userinfo?access_token={$result['access_token']}&openid={$result['openid']}&lang={$lang}"; // $return = $this->curl->doGet($url); // 這介面有病 強制顯示檔案頭 $return = file_get_contents($url); if (!$return) { $this->msg = '獲取使用者資訊失敗'; return false; } $return = json_decode($return, true); if (!$return) { $this->msg = '獲取使用者資訊返回失敗'; return false; } // file_put_contents('ccc.txt',print_r($return,true),FILE_APPEND); $data = array( 'openid' => $return['openid'], 'name' => $return['nickname'], 'sex' => $return['sex'], 'province' => $return['province'], 'city' => $return['city'], 'country' => $return['country'], 'img' => $return['headimgurl'], 'bindtel' => 0, ); } else { $data = array( 'openid' => $result['openid'], 'username' => "微信使用者_" . random(6, 1) ); } $name = rand(100000, 1000000000); $e = $name . "@qq.com"; $password = $e; $id = UserAddEdit(0, $data['username'], $password, $e, 10, 0, "", $msg); if ($id <= 0) { $this->msg = $msg; return false; } C::t(PT_USER)->update($data, $id); $member = C::t(PT_USER)->get($id); return $member; } } /* 公眾號 安全中心 設定IP白名單 公眾號的全域性唯一介面呼叫憑據,公眾號呼叫各介面時都需使用access_token。開發者需要進行妥善儲存。access_token的儲存至少要保留512個字元空間。access_token的有效期目前為2個小時,需定時重新整理,重複獲取將導致上次獲取的access_token失效。 */ public function getAccessToken($type) { $addtime = TIMESTAMP - 7200; $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$this->appid}&secret={$this->appserect}"; $row = C::t(PT_WXTOKEN)->getNew($addtime, $type); if ($row) { return $row['access_token']; } else { $result = $this->curl->doGet($url); if (!$result) { $this->msg = "無法獲取令牌內容"; return false; } $result = json_decode($result, true); if (!$result) { $this->msg = "解析令牌內容失敗"; return false; } if ($result['access_token']) { C::t(PT_WXTOKEN)->addToken($result['access_token'], $type); return $result['access_token']; } else { $this->msg = "獲取令牌失敗"; return false; } } } // 獲取js票據 需要在公眾號設定 - 功能設定 - JS介面安全域名設定 public function getJsTicket() { $addtime = TIMESTAMP - 7200; $row = C::t(PT_WXTICKET)->getNew($addtime); if ($row) { return $row['ticket']; } else { $token = $this->getAccessToken(); if (!$token) { return false; } $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={$token}&type=jsapi"; $result = $this->curl->doGet($url); if (!$result) { $this->msg = "無法獲取js票據"; return false; } $result = json_decode($result, true); if (!$result) { $this->msg = "解析js票據內容失敗"; return false; } if ($result['ticket']) { C::t(PT_WXTICKET)->addTicket($result['ticket']); return $result['ticket']; } else { $this->msg = "獲取js票據失敗"; return false; } } } // js sdk 票據簽名 當前網頁的URL,不包含#及其後面部分 public function jsSign($data) { // 1.所有待簽名引數按照欄位名的ASCII 碼從小到大排序(字典序) ksort($data); // 2.URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字串string1 採用原始值,不進行URL 轉義 $string1 = $this->ToUrlParams($data); // echo "string1:{$string1}<br/>"; // 3.對string1做sha1加密 $sign = sha1($string1); // echo "signature:{$sign}<br/>"; return $sign; } // 獲取訊息內容 public function getMsg() { return $this->msg; } /** * 格式化引數格式化成url引數 */ public function ToUrlParams($data) { $buff = ""; foreach ($data as $k => $v) { if ($k != "sign" && $v != "" && !is_array($v)) { $buff.= $k . "=" . $v . "&"; } } $buff = trim($buff, "&"); return $buff; } } ?>

登入

// 微信登入
function wxlogin() {
    global $_G,$identifier,$config,$wx;
    if (!$_G['uid']) {
        if ($_GET['state']) {
            //回撥
            $member = $wx->getUserInfo($_GET['code']);
            if (!$member) {
                exit($wx->getMsg());
            }
            if (!function_exists("setloginstatus")) {
                include_once libfile('function/member');
            }
            // 設定登入狀態$wx
            setloginstatus($member, 2592000);
            checkfollowfeed();
            $_G['uid'] = $member['uid'];
            $_G['member'] = $member;
        } else {
            //請求授權 對引數編碼
            $redirect = urlencode(getProtocol() . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
            $wx->getCode($redirect, 'snsapi_base');
        }
    }
}
function getProtocol() {
    return is_HTTPS() ? 'https://' : 'http://';
}
function is_HTTPS() {  if ($_SERVER['HTTPS'] === 1 || $_SERVER['HTTPS'] === 'on' || $_SERVER['SERVER_PORT'] == 443) {
        return true;
    }
    return false;
}