網站微信掃碼登入的實作
- 一些需要注意的事項:
- 相關CODE:
- 開發說明-流程
-
- 第一步:請求CODE
- 第二步:通過code擷取access_token
- 第三步:通過access_token調用接口
一些需要注意的事項:
1,基于微信開放平台
2,微信公衆号與微信開放平台的openid不一緻
3,UINIONID唯一
相關CODE:
View:
<script src="http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js"></script>
<script>
var obj = new WxLogin({
self_redirect:false,
id:"login_container",
appid: "wx8bc3b06bb396fc25",
scope: "snsapi_login",
redirect_uri: encodeURI("http://www.51666219.com/bb/auth/dowxlogin"),
state: "STATE"
});
</script>
Control:
require __DIR__ . '/../../../vendor/autoload.php';
$url = 'https://api.weixin.qq.com/sns/oauth2/access_token?';
$params = array(
'appid' => C('WECHAT.APPID'),
'secret' => C('WECHAT.SECRET'),
'code' => $_GET['code'],
'grant_type' => 'authorization_code');
//Zlog($url . http_build_query($params), 'dowxlogin => Req URL');
$resp = Requests::get($url . http_build_query($params));
//Zlog(dump($resp,false),'RefreshAccessToken => Resp');
if ($resp->status_code != 200) {
$this->error( '微信服務異常,請稍候再試!errorcode ='."$resp->status_code" );
}
$data = json_decode($resp->body, true);
if (isset($data['errcode']) && $data['errcode'] != 0) {
throw new \Exception($data['errmsg'], $data['errcode']);
}
$model = M('Bbuser');
$user = $model->where( array('unionid' => $data['unionid']) )->find();
if ( empty($user) ) {
$url = 'https://api.weixin.qq.com/sns/userinfo?';
$params = array(
'access_token' => $data['access_token'],
'openid' => $data['openid'],
'lang' => 'zh_CN');
$resp = Requests::get($url . http_build_query($params));
//Zlog(dump($resp,false),'RESP');
if ($resp->status_code != 200) {
$this->error( '微信服務異常,請稍候再試!errorcode ='."$resp->status_code" );
}
$data = json_decode($resp->body, true);
開發說明-流程
詳見 微信開放平台 開發文檔
https://open.weixin.qq.com
為了讓使用者登入網站的門檻更低,微信掃一掃登入變得越來越廣泛。
此篇文字的出發點基于微信開放平台已經配置好域名(80端口)并且認證成功獲得app_id和secret并有權限調用微信的接口。好了,就先談一談微信掃碼登入的整個流程吧。
微信OAuth2.0授權登入目前支援authorization_code模式,适用于擁有server端的應用授權。該模式整體流程為:
- 第三方發起微信授權登入請求,微信使用者允許授權第三方應用後,微信會拉起應用或重定向到第三方網站,并且帶上授權臨時票據code參數;
- 通過code參數加上AppID和AppSecret等,通過API換取access_token;
-
通過access_token進行接口調用,擷取使用者基本資料資源或幫助使用者實作基本操作。
擷取access_token時序圖:
第一步:請求CODE
第三方使用網站應用授權登入前請注意已擷取相應網頁授權作用域(scope=snsapi_login),則可以通過在PC端打開以下連結:
https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
若提示“該連結無法通路”,請檢查參數是否填寫錯誤,如redirect_uri的域名與稽核時填寫的授權域名不一緻或scope不為snsapi_login。
參數說明
參數 是否必須 說明
appid 是 應用唯一辨別
redirect_uri 是 請使用urlEncode對連結進行處理
response_type 是 填code
scope 是 應用授權作用域,擁有多個作用域用逗号(,)分隔,網頁應用目前僅填寫snsapi_login即
state 否 用于保持請求和回調的狀态,授權請求後原樣帶回給第三方。該參數可用于防止csrf攻擊(跨站請求僞造攻擊),建議第三方帶上該參數,可設定為簡單的随機數加session進行校驗
傳回說明
使用者允許授權後,将會重定向到redirect_uri的網址上,并且帶上code和state參數
redirect_uri?code=CODE&state=STATE
若使用者禁止授權,則重定向後不會帶上code參數,僅會帶上state參數
redirect_uri?state=STATE
微信使用者使用微信掃描二維碼并且确認登入後,PC端會跳轉到
https://passport.yhd.com/wechat/callback.do?code=CODE&state=3d6be0a4035d839573b04816624a415e
為了滿足網站更定制化的需求,我們還提供了第二種擷取code的方式,支援網站将微信登入二維碼内嵌到自己頁面中,使用者使用微信掃碼授權後通過JS将code傳回給網站。
JS微信登入主要用途:網站希望使用者在網站内就能完成登入,無需跳轉到微信域下登入後再傳回,提升微信登入的流暢性與成功率。 網站内嵌二維碼微信登入JS實作辦法:
步驟1:在頁面中先引入如下JS檔案(支援https):
http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js
步驟2:在需要使用微信登入的地方執行個體以下JS對象:
var obj = new WxLogin({
self_redirect:true,
id:“login_container”,
appid: “”,
scope: “”,
redirect_uri: “”,
state: “”,
style: “”,
href: “”
});
參數說明
參數 是否必須 說明
self_redirect 否 true:手機點選确認登入後可以在 iframe 内跳轉到 redirect_uri,false:手機點選确認登入後可以在 top window 跳轉到 redirect_uri。預設為 false。
id 是 第三方頁面顯示二維碼的容器id
appid 是 應用唯一辨別,在微信開放平台送出應用稽核通過後獲得
scope 是 應用授權作用域,擁有多個作用域用逗号(,)分隔,網頁應用目前僅填寫snsapi_login即可
redirect_uri 是 重定向位址,需要進行UrlEncode
state 否 用于保持請求和回調的狀态,授權請求後原樣帶回給第三方。該參數可用于防止csrf攻擊(跨站請求僞造攻擊),建議第三方帶上該參數,可設定為簡單的随機數加session進行校驗
style 否 提供"black"、"white"可選,預設為黑色文字描述。詳見文檔底部FAQ
href 否 自定義樣式連結,第三方可根據實際需求覆寫預設樣式。詳見文檔底部FAQ
第二步:通過code擷取access_token
通過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
傳回說明
正确的傳回:
{
“access_token”:“ACCESS_TOKEN”,
“expires_in”:7200,
“refresh_token”:“REFRESH_TOKEN”,
“openid”:“OPENID”,
“scope”:“SCOPE”,
“unionid”: “o6_bmasdasdsad6_2sgVt7hMZOPfL”
}
參數說明
參數 說明
access_token 接口調用憑證
expires_in access_token接口調用憑證逾時時間,機關(秒)
refresh_token 使用者重新整理access_token
openid 授權使用者唯一辨別
scope 使用者授權的作用域,使用逗号(,)分隔
unionid 當且僅當該網站應用已獲得該使用者的userinfo授權時,才會出現該字段。
錯誤傳回樣例:
{“errcode”:40029,“errmsg”:“invalid code”}
重新整理access_token有效期
access_token是調用授權關系接口的調用憑證,由于access_token有效期(目前為2個小時)較短,當access_token逾時後,可以使用refresh_token進行重新整理,access_token重新整理結果有兩種:
- 若access_token已逾時,那麼進行refresh_token會擷取一個新的access_token,新的逾時時間;
-
若access_token未逾時,那麼進行refresh_token不會改變access_token,但逾時時間會重新整理,相當于續期access_token。
refresh_token擁有較長的有效期(30天),當refresh_token失效的後,需要使用者重新授權。
請求方法
擷取第一步的code後,請求以下連結進行refresh_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參數
傳回說明
正确的傳回:
{
“access_token”:“ACCESS_TOKEN”,
“expires_in”:7200,
“refresh_token”:“REFRESH_TOKEN”,
“openid”:“OPENID”,
“scope”:“SCOPE”
}
參數說明
參數 說明
access_token 接口調用憑證
expires_in access_token接口調用憑證逾時時間,機關(秒)
refresh_token 使用者重新整理access_token
openid 授權使用者唯一辨別
scope 使用者授權的作用域,使用逗号(,)分隔
錯誤傳回樣例:
{“errcode”:40030,“errmsg”:“invalid refresh_token”}
注意:
1、Appsecret 是應用接口使用密鑰,洩漏後将可能導緻應用資料洩漏、應用的使用者資料洩漏等高風險後果;存儲在用戶端,極有可能被惡意竊取(如反編譯擷取Appsecret);
2、access_token 為使用者授權第三方應用發起接口調用的憑證(相當于使用者登入态),存儲在用戶端,可能出現惡意擷取access_token 後導緻的使用者資料洩漏、使用者微信相關接口功能被惡意發起等行為;
3、refresh_token 為使用者授權第三方應用的長效憑證,僅用于重新整理access_token,但洩漏後相當于access_token 洩漏,風險同上。
建議将secret、使用者資料(如access_token)放在App雲端伺服器,由雲端中轉接口調用請求。
第三步:通過access_token調用接口
擷取access_token後,進行接口調用,有以下前提:
- access_token有效且未逾時;
-
微信使用者已授權給第三方應用帳号相應接口作用域(scope)。
對于接口作用域(scope),能調用的接口有以下:
授權作用域(scope) 接口 接口說明
snsapi_base /sns/oauth2/access_token 通過code換取access_token、refresh_token和已授權scope
snsapi_base /sns/oauth2/refresh_token 重新整理或續期access_token使用
snsapi_base /sns/auth 檢查access_token有效性
snsapi_userinfo /sns/userinfo 擷取使用者個人資訊
其中snsapi_base屬于基礎接口,若應用已擁有其它scope權限,則預設擁有snsapi_base的權限。使用snsapi_base可以讓移動端網頁授權繞過跳轉授權登入頁請求使用者授權的動作,直接跳轉第三方網頁帶上授權臨時票據(code),但會使得使用者已授權作用域(scope)僅為snsapi_base,進而導緻無法擷取到需要使用者授權才允許獲得的資料和基礎功能。
接口調用方法可查閱《微信授權關系接口調用指南》
F.A.Q
.
什麼是授權臨時票據(code)?
答:第三方通過code進行擷取access_token的時候需要用到,code的逾時時間為10分鐘,一個code隻能成功換取一次access_token即失效。code的臨時性和一次保障了微信授權登入的安全性。第三方可通過使用https和state參數,進一步加強自身授權登入的安全性。
.
.
什麼是授權作用域(scope)?
答:授權作用域(scope)代表使用者授權給第三方的接口權限,第三方應用需要向微信開放平台申請使用相應scope的權限後,使用文檔所述方式讓使用者進行授權,經過使用者授權,擷取到相應access_token後方可對接口進行調用。
.
.網站内嵌二維碼微信登入JS代碼中style字段作用?
答:第三方頁面顔色風格可能為淺色調或者深色調,若第三方頁面為淺色背景,style字段應提供"black"值(或者不提供,black為預設值),則對應的微信登入文字樣式為黑色。相關效果如下:
若提供"white"值,則對應的文字描述将顯示為白色,适合深色背景。相關效果如下:
4.網站内嵌二維碼微信登入JS代碼中href字段作用?
答:如果第三方覺得微信團隊提供的預設樣式與自己的頁面樣式不比對,可以自己提供樣式檔案來覆寫預設樣式。舉個例子,如第三方覺得預設二維碼過大,可以提供相關css樣式檔案,并把連結位址填入href字段
.impowerBox .qrcode {width: 200px;}
.impowerBox .title {display: none;}
.impowerBox .info {width: 200px;}
.status_icon {display: none}
.impowerBox .status {text-align: center;}
版權所有 益久科技–專注于IT外包服務