微信公眾平台開發 OAuth2.0網頁授權認證


一、什么是OAuth2.0

官方網站:http://oauth.NET/   http://oauth.Net/2/

權威定義:OAuth is An open protocol to allow secure authorization in a simple and standard method from web, mobile and desktop applications. 

OAuth是一個開放協議,允許用戶讓第三方應用以安全且標准的方式獲取該用戶在某一網站、移動或桌面應用上存儲的私密的資源(如用戶個人信息、照片、視頻、聯系人列表),而無需將用戶名和密碼提供給第三方應用。

OAuth 2.0是OAuth協議的下一版本,但不向后兼容OAuth 1.0。 OAuth 2.0關注客戶端開發者的簡易性,同時為Web應用,桌面應用和手機,和起居室設備提供專門的認證流程。

OAuth允許用戶提供一個令牌,而不是用戶名和密碼來訪問他們存放在特定服務提供者的數據。每一個令牌授權一個特定的網站(例如,視頻編輯網站)在特定的時段(例如,接下來的2小時內)內訪問特定的資源(例如僅僅是某一相冊中的視頻)。這樣,OAuth允許用戶授權第三方網站訪問他們存儲在另外的服務提供者上的信息,而不需要分享他們的訪問許可或他們數據的所有內容。

新浪微博API目前也使用OAuth 2.0。

二、微信公眾平台OAuth2.0授權

微信公眾平台OAuth2.0授權詳細步驟如下:

1. 用戶關注微信公眾賬號。
2. 微信公眾賬號提供用戶請求授權頁面URL。
3. 用戶點擊授權頁面URL,將向服務器發起請求
4. 服務器詢問用戶是否同意授權給微信公眾賬號(scope為snsapi_base時無此步驟)
5. 用戶同意(scope為snsapi_base時無此步驟)
6. 服務器將CODE通過回調傳給微信公眾賬號
7. 微信公眾賬號獲得CODE
8. 微信公眾賬號通過CODE向服務器請求Access Token
9. 服務器返回Access Token和OpenID給微信公眾賬號
10. 微信公眾賬號通過Access Token向服務器請求用戶信息(scope為snsapi_base時無此步驟)
11. 服務器將用戶信息回送給微信公眾賬號(scope為snsapi_base時無此步驟)

如果用戶在微信中(Web微信除外)訪問公眾號的第三方網頁,公眾號開發者可以通過此接口獲取當前用戶基本信息(包括昵稱、性別、城市、國家)。利用用戶信息,可以實現體驗優化、用戶來源統計、帳號綁定、用戶身份鑒權等功能。請注意,“獲取用戶基本信息接口是在用戶和公眾號產生消息交互時,才能根據用戶OpenID獲取用戶基本信息,而網頁授權的方式獲取用戶基本信息,則無需消息交互,只是用戶進入到公眾號的網頁,就可彈出請求用戶授權的界面,用戶授權后,就可獲得其基本信息(此過程甚至不需要用戶已經關注公眾號。)”

微信OAuth2.0授權登錄讓微信用戶使用微信身份安全登錄第三方應用或網站,在微信用戶授權登錄已接入微信OAuth2.0的第三方應用后,第三方可以獲取到用戶的接口調用憑證(access_token),通過access_token可以進行微信開放平台授權關系接口調用,從而可實現獲取微信用戶基本開放信息和幫助用戶實現基礎開放功能等。

在微信公眾號請求用戶網頁授權之前,開發者需要先到公眾平台網站的我的服務頁中配置授權回調域名。請注意,這里填寫的域名不要加http://

關於配置授權回調域名的說明:

授權回調域名配置規范為全域名,比如需要網頁授權的域名為: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鑒權。

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

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

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

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

  4. 通過網頁授權access_token和openid獲取用戶基本信息

目錄

[隱藏]

第一步:用戶同意授權,獲取code

在確保微信公眾賬號擁有授權作用域(scope參數)的權限的前提下(服務號獲得高級接口后,默認帶有scope參數中的snsapi_base和snsapi_userinfo),引導關注者打開如下頁面:

https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect 若提示“該鏈接無法訪問”,請檢查參數是否填寫錯誤,是否擁有scope參數對應的授權作用域權限。
參考鏈接(請在微信客戶端中打開此鏈接體驗) Scope為snsapi_base https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx520c15f417810387&redirect_uri=http%3A%2F%2Fchong.qq.com%2Fphp%2Findex.php%3Fd%3D%26c%3DwxAdapter%26m%3DmobileDeal%26showwxpaytitle%3D1%26vb2ctag%3D4_2030_5_1194_60&response_type=code&scope=snsapi_base&state=123#wechat_redirect Scope為snsapi_userinfo https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxf0e81c3bee622d60&redirect_uri=http%3A%2F%2Fnba.bluewebgame.com%2Foauth_response.php&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect

參數說明

參數 是否必須 說明
appid 公眾號的唯一標識
redirect_uri 授權后重定向的回調鏈接地址,請使用urlencode對鏈接進行處理
response_type 返回類型,請填寫code
scope 應用授權作用域,snsapi_base (不彈出授權頁面,直接跳轉,只能獲取用戶openid),snsapi_userinfo (彈出授權頁面,可通過openid拿到昵稱、性別、所在地。並且,即使在未關注的情況下,只要用戶授權,也能獲取其信息)
state 重定向后會帶上state參數,開發者可以填寫a-zA-Z0-9的參數值
#wechat_redirect 無論直接打開還是做頁面302重定向時候,必須帶此參數

下圖為scope等於snsapi_userinfo時的授權頁面:

 

用戶同意授權后

如果用戶同意授權,頁面將跳轉至 redirect_uri/?code=CODE&state=STATE。若用戶禁止授權,則重定向后不會帶上code參數,僅會帶上state參數redirect_uri?state=STATE

code說明 : code作為換取access_token的票據,每次用戶授權帶上的code將不一樣,code只能使用一次,5分鍾未被使用自動過期。

第二步:通過code換取網頁授權access_token

首先請注意,這里通過code換取的網頁授權access_token,與基礎支持中的access_token不同。公眾號可通過下述接口來獲取網頁授權access_token。如果網頁授權的作用域為snsapi_base,則本步驟中獲取到網頁授權access_token的同時,也獲取到了openid,snsapi_base式的網頁授權流程即到此為止。

請求方法

獲取code后,請求以下鏈接獲取access_token:  https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

參數說明

參數 是否必須 說明
appid 公眾號的唯一標識
secret 公眾號的appsecret
code 填寫第一步獲取的code參數
grant_type 填寫為authorization_code

返回說明

正確時返回的JSON數據包如下:

{    "access_token":"ACCESS_TOKEN",    "expires_in":7200,    "refresh_token":"REFRESH_TOKEN",    "openid":"OPENID",    "scope":"SCOPE" }
參數 描述
access_token 網頁授權接口調用憑證,注意:此access_token與基礎支持的access_token不同
expires_in access_token接口調用憑證超時時間,單位(秒)
refresh_token 用戶刷新access_token
openid 用戶唯一標識,請注意,在未關注公眾號時,用戶訪問公眾號的網頁,也會產生一個用戶和公眾號唯一的OpenID
scope 用戶授權的作用域,使用逗號(,)分隔


錯誤時微信會返回JSON數據包如下(示例為Code無效錯誤):

{"errcode":40029,"errmsg":"invalid code"}

全局返回碼說明

第三步:刷新access_token(如果需要)

由於access_token擁有較短的有效期,當access_token超時后,可以使用refresh_token進行刷新,refresh_token擁有較長的有效期(7天、30天、60天、90天),當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
參數 是否必須 說明
appid 公眾號的唯一標識
grant_type 填寫為refresh_token
refresh_token 填寫通過access_token獲取到的refresh_token參數

返回說明

正確時返回的JSON數據包如下:

{    "access_token":"ACCESS_TOKEN",    "expires_in":7200,    "refresh_token":"REFRESH_TOKEN",    "openid":"OPENID",    "scope":"SCOPE" }
參數 描述
access_token 網頁授權接口調用憑證,注意:此access_token與基礎支持的access_token不同
expires_in access_token接口調用憑證超時時間,單位(秒)
refresh_token 用戶刷新access_token
openid 用戶唯一標識
scope 用戶授權的作用域,使用逗號(,)分隔


錯誤時微信會返回JSON數據包如下(示例為Code無效錯誤):

{"errcode":40029,"errmsg":"invalid code"}

全局返回碼說明

第四步:拉取用戶信息(需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 網頁授權接口調用憑證,注意:此access_token與基礎支持的access_token不同
openid 用戶的唯一標識
lang 返回國家地區語言版本,zh_CN 簡體,zh_TW 繁體,en 英語

返回說明

正確時返回的JSON數據包如下:

{    "openid":" OPENID",    " nickname": NICKNAME,    "sex":"1",    "province":"PROVINCE"    "city":"CITY",    "country":"COUNTRY",     "headimgurl":    "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",  "privilege":[ "PRIVILEGE1" "PRIVILEGE2"     ] }
參數 描述
openid 用戶的唯一標識
nickname 用戶昵稱
sex 用戶的性別,值為1時是男性,值為2時是女性,值為0時是未知
province 用戶個人資料填寫的省份
city 普通用戶個人資料填寫的城市
country 國家,如中國為CN
headimgurl 用戶頭像,最后一個數值代表正方形頭像大小(有0、46、64、96、132數值可選,0代表640*640正方形頭像),用戶沒有頭像時該項為空
privilege 用戶特權信息,json 數組,如微信沃卡用戶為(chinaunicom)


錯誤時微信會返回JSON數據包如下(示例為openid無效):

{"errcode":40003,"errmsg":" invalid openid "}

全局返回碼說明

附:檢驗授權憑證(access_token)是否有效

請求方法

http:GET(請使用https協議) https://api.weixin.qq.com/sns/auth?access_token=ACCESS_TOKEN&openid=OPENID

參數說明

參數 描述
access_token 網頁授權接口調用憑證,注意:此access_token與基礎支持的access_token不同
openid 用戶的唯一標識

返回說明

正確的Json返回結果:

{ "errcode":0,"errmsg":"ok"}

錯誤時的Json返回示例:

{ "errcode":40003,"errmsg":"invalid openid"}

 案例代碼:

請求授權頁面的構造方式

url在線編碼工具:http://tool.oschina.net/encode?type=4

https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

前端代碼


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd";><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><meta name="viewport" content="width=device-width,height=device-height,inital-scale=1.0,maximum-scale=1.0,user-scalable=no;"><meta name="apple-mobile-web-app-capable" content="yes"><meta name="apple-mobile-web-app-status-bar-style" content="black"><meta name="format-detection" content="telephone=no"><title>會員注冊</title><script type="text/JavaScript" src="jQuery.js"></script>

 <script type="text/javascript"> 
  function callback(result) {  
        alert('cucess');         
  alert(result);  //輸出openid    
  } 
  
  function getQueryString(name) {  
   var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");   
   var r = window.location.search.substr(1).match(reg);    
   if (r != null) return unescape(r[2]); return null;   
  }
  var code = getQueryString("code");
  
  $.ajax({ 
  async: false,       url: "http://atest.sinaapp.com/oauth2.php", //這是我的服務端處理文件PHP的     
  type: "GET",       //下面幾行是jsoup,如果去掉下面幾行的注釋,后端對應的返回結果也要去掉注釋      
  // dataType: 'jsonp',      
  // jsonp: 'callback', //jsonp的值自定義,如果使用jsoncallback,那么服務器端,要返回一個jsoncallback的值對應的對象.       
  // jsonpCallback:'callback',      
  data: {code:code}, //傳遞本頁面獲取的code到后台,以便后台獲取openid      
  timeout: 5000,       
  success: function (result) { 
        callback(result);     
  },       
  error: function (jqXHR, textStatus, errorThrown) {
  alert(textStatus);       }   
  });
  
  </script>
  
  </head><body></body> 


后端代碼


<?php
$code = $_GET['code'];//前端傳來的code值
$appid = "wx468622291a1e99d6";
$appsecret = "98566dc38863aa4395fabebb0de6ecc1";//獲取openid
$url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=$appid&secret=$appsecret&code=$code&grant_type=authorization_code";
$result = https_request($url);
$jsoninfo = json_decode($result, true);
$openid = $jsoninfo["openid"];//從返回json結果中讀出openid
$access_token = $jsoninfo["access_token"];//從返回json結果中讀出openid
$callback=$_GET['callback'];  // echo $callback."({result:'".$openid."'})";

$url1 = "https://api.weixin.qq.com/sns/userinfo?access_token=$access_token&openid=$openid&lang=zh_CN";
$result1 = https_request($url1);
$jsoninfo1 = json_decode($result1, true);
$nickname=$jsoninfo1["nickname"];
echo $openid.":".$access_token.":".$nickname; //把openid 送回前端

 function https_request($url,$data = null){
  $curl = curl_init();   
  curl_setopt($curl, CURLOPT_URL, $url);   
  curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);   
  curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);    
  if (!empty($data)){    
  curl_setopt($curl, CURLOPT_POST, 1);  
  curl_setopt($curl, CURLOPT_POSTFIELDS, $data);   
  }    
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 
  $output = curl_exec($curl);    
  curl_close($curl);    
  return $output;
 }


?>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM