微信網頁受權

  1、 問題  javascript

  有時候,在微信客戶端外點擊一個連接:html

  1.會提示此連接必須在微信客戶端訪問,這是爲何呢?前端

  2.在微信客戶端中訪問第三方網頁,爲何會出現一個頁面,上面要獲取你的我的信息,讓你肯定後才能進入呢?java

 

  2、解答這兩個問題以前,咱們先了解一點微信開發的規範。(此處參看微信公衆平臺開發文檔) android

  爲了識別用戶,每一個用戶針對每一個公衆號會產生一個安全的OpenID,若是須要在多公衆號、移動應用之間作用戶共通,則需前往微信開放平臺,將這些公衆號和應用綁定到一個開放平臺帳號下,綁定後,一個用戶雖然對多個公衆號和應用有多個不一樣的OpenID,但他對全部這些同一開放平臺帳號下的公衆號和應用,只有一個UnionID,能夠在用戶管理-獲取用戶基本信息(UnionID機制)文檔瞭解詳情。ios

  關於網頁受權回調域名的說明後端

  一、在微信公衆號請求用戶網頁受權以前,開發者須要先到公衆平臺官網中的「開發 - 接口權限 - 網頁服務 - 網頁賬號 - 網頁受權獲取用戶基本信息」的配置選項中,修改受權回調域名。請注意,這裏填寫的是域名(是一個字符串),而不是URL,所以請勿加 http:// 等協議頭; api

  二、受權回調域名配置規範爲全域名,好比須要網頁受權的域名爲:www.qq.com,配置之後此域名下面的頁面http://www.qq.com/music.html 、 http://www.qq.com/login.html 均可以進行OAuth2.0鑑權。但http://pay.qq.com 、 http://music.qq.com 、 http://qq.com沒法進行OAuth2.0鑑權 瀏覽器

  三、若是公衆號登陸受權給了第三方開發者來進行管理,則沒必要作任何設置,由第三方代替公衆號實現網頁受權便可 安全

  

  關於網頁受權的兩種scope的區別說明

  一、以snsapi_base爲scope發起的網頁受權,是用來獲取進入頁面的用戶的openid的,而且是靜默受權並自動跳轉到回調頁的。用戶感知的就是直接進入了回調頁(每每是業務頁面)

  二、以snsapi_userinfo爲scope發起的網頁受權,是用來獲取用戶的基本信息的。但這種受權須要用戶手動贊成,而且因爲用戶贊成過,因此無須關注,就可在受權後獲取該用戶的基本信息。 

  三、用戶管理類接口中的「獲取用戶基本信息接口」,是在用戶和公衆號產生消息交互或關注後事件推送後,才能根據用戶OpenID來獲取用戶基本信息。這個接口,包括其餘微信接口,都是須要該用戶(即openid)關注了公衆號後,才能調用成功的。 

 

  關於網頁受權access_token和普通access_token的區別

  一、微信網頁受權是經過OAuth2.0機制實現的,在用戶受權給公衆號後,公衆號能夠獲取到一個網頁受權特有的接口調用憑證(網頁受權access_token),經過網頁受權access_token能夠進行受權後接口調用,如獲取用戶基本信息; 

  二、其餘微信接口,須要經過基礎支持中的「獲取access_token」接口來獲取到的普通access_token調用。 

 

  關於UnionID機制

  一、請注意,網頁受權獲取用戶基本信息也遵循UnionID機制。即若是開發者有在多個公衆號,或在公衆號、移動應用之間統一用戶賬號的需求,須要前往微信開放平臺(open.weixin.qq.com)綁定公衆號後,纔可利用UnionID機制來知足上述需求。 

  二、UnionID機制的做用說明:若是開發者擁有多個移動應用、網站應用和公衆賬號,可經過獲取用戶基本信息中的unionid來區分用戶的惟一性,由於同一用戶,對同一個微信開放平臺下的不一樣應用(移動應用、網站應用和公衆賬號),unionid是相同的。

 

  關於特殊場景下的靜默受權

  一、上面已經提到,對於以snsapi_base爲scope的網頁受權,就靜默受權的,用戶無感知; 

  二、對於已關注公衆號的用戶,若是用戶從公衆號的會話或者自定義菜單進入本公衆號的網頁受權頁,即便是scope爲snsapi_userinfo,也是靜默受權,用戶無感知。

  

  3、問題解答 

  問題一:

  言歸正傳,首先解答下第一個問題,很簡單,由於開發的時候,我們都會知道,開發的是否是微信端頁面(哈哈)。要求在微信裏打開的,可能須要獲取微信頭像,所在地區等參數。若是在瀏覽器裏面直接打開的話,這些參數獲取不到,可能後面的程序就無法往下執行,因此要求用微信客戶端打開。

  是否是微信客戶端打開,就是判斷打開連接的瀏覽器是什麼的唄,這裏只須要用js判斷一下就好了,下面是代碼,順帶贈送,安卓和ios客戶端的判斷,網上一搜也是一大把。

    //判斷是否爲微信
    function Is_WeiXin() {
        var ua = window.navigator.userAgent.toLowerCase();
        if (ua.match(/MicroMessenger/i) == 'micromessenger') {
            return true;
        } else {
            return false;
        }
    }

    //判斷是否爲安卓
    function Is_Android() {
        var u = navigator.userAgent;
        var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android終端
        return isAndroid;
    }

    //判斷是否爲IOS
    function Is_Ios() {
        var u = navigator.userAgent;
        var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios終端
        return isiOS;
    }

  

    if (IsWeiXin) {
            document.getElementById("message").className = "flxed";
        } else {
            if (IsAndroid || IsIos) {
                if (IsAndroid) {
                    self.location.href =Url_Android;
                    return;
                }
                if (IsIos) {
                    self.location.href = Url_Ios;
                    return;
                }
            } else {
                alert("咱們暫時沒有可供您設備運行的版本,感謝您的支持!");
                return;
            }
        }

  

  問題二:

  關於這個問題,這就涉及到微信網頁受權,若是你一直不理解,我建議,你把我上面的標題二,認真多讀個幾遍,書讀百遍其義自見,一點都不假,關鍵你得用心讀下去,或者看開發文檔(https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842),拿走不謝。

 

  具體而言,網頁受權流程分爲四步:

  一、引導用戶進入受權頁面贊成受權,獲取code 

  二、經過code換取網頁受權access_token(與基礎支持中的access_token不一樣) 

  三、若是須要,開發者能夠刷新網頁受權access_token,避免過時 

  四、經過網頁受權access_token和openid獲取用戶基本信息(支持UnionID機制) 

 

  第一步:用戶贊成受權,獲取code

  下圖爲scope等於snsapi_userinfo時的受權頁面:

  

  用戶贊成受權後,若是用戶贊成受權,頁面將跳轉至 redirect_uri/?code=CODE&state=STATE。

  code說明 : code做爲換取access_token的票據,每次用戶受權帶上的code將不同,code只能使用一次,5分鐘未被使用自動過時。 

   

  第二步:經過code換取網頁受權access_token

  首先請注意,這裏經過code換取的是一個特殊的網頁受權access_token,與基礎支持中的access_token(該access_token用於調用其餘接口)不一樣。公衆號可經過下述接口來獲取網頁受權access_token。若是網頁受權的做用域爲snsapi_base,則本步驟中獲取到網頁受權access_token的同時,也獲取到了openid(用戶的惟一標識),snsapi_base式的網頁受權流程即到此爲止。

尤爲注意:因爲公衆號的secret和獲取到的access_token安全級別都很是高,必須只保存在服務器,不容許傳給客戶端。後續刷新access_token、經過access_token獲取用戶信息等步驟,也必須從服務器發起。

請求方法
獲取code後,請求如下連接獲取access_token:  https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code 

正確時返回的JSON數據包以下:
{ "access_token":"ACCESS_TOKEN",    
 "expires_in":7200,    
 "refresh_token":"REFRESH_TOKEN",    
 "openid":"OPENID",    
 "scope":"SCOPE" } 

錯誤時微信會返回JSON數據包以下(示例爲Code無效錯誤):
{"errcode":40029,"errmsg":"invalid code"} 

  

  第三步:刷新access_token(若是須要)

  因爲access_token擁有較短的有效期,當access_token超時後,可使用refresh_token進行刷新,refresh_token有效期爲30天,當refresh_token失效以後,須要用戶從新受權。

請求方法
獲取第二步的refresh_token後,請求如下連接獲取access_token:  
https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN 

正確時返回的JSON數據包以下:
{ "access_token":"ACCESS_TOKEN",  
 "expires_in":7200,   
 "refresh_token":"REFRESH_TOKEN",   
 "openid":"OPENID",   
 "scope":"SCOPE" } 

  

  第四步:拉取用戶信息(需scope爲 snsapi_userinfo)

  若是網頁受權做用域爲snsapi_userinfo,則此時開發者能夠經過access_token和openid拉取用戶信息了。

請求方法
http:GET(請使用https協議) https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN 

附:檢驗受權憑證(access_token)是否有效
請求方法
http:GET(請使用https協議) https://api.weixin.qq.com/sns/auth?access_token=ACCESS_TOKEN&openid=OPENID 

  

  以上說了這麼多,小結一下,如下邏輯,認爲是用戶首次登錄。

  第一步:點擊url連接,判斷用戶是否登陸(方法:根據查找本地是否有基礎的access_token

  第二步:若是查到基礎的access_token(一個憑證),則已經登陸,就跳轉到相應的頁面

      若是沒有找到token,則沒有登陸過。

  第三步:沒有登陸過:

      1. 受權,拉取微信code,(方法:問題二的第一步)

      2.截取到code,調接口,將code返回給後端。

      3.後端拿到code,換取特殊的網頁受權access_token(問題二的第二步,本步驟中獲取到網頁受權access_token的同時,也獲取到了openid(用戶的惟一標識),問題二的第三步和第四步都可執行)

      4.後端根據openId,判斷此用戶是否在用戶系統(便是否註冊過)

        a、在用戶系統。返回給前端基礎的access_token,前端將基礎的access_token存在本地(本地有了基礎的access_token,下次登陸便可直接跳轉目的頁),跳轉頁面

        b、不在用戶系統。後端返給前端該用戶的openId,輸入手機號和驗證碼,調接口,把openId,手機傳給後臺,後臺將信息存入用戶系統,生成一個基礎的access_token憑證,返回給前端,前端存儲,跳轉頁面,接下來Ajax請求API時,帶上token,過濾器校驗token,經過就返回數據,展現數據,未經過就返回錯誤碼提示錯誤信息

 

相關文章
相關標籤/搜索