1. 程式人生 > >第三方微信登入 | 靜默授權與網頁授權的實現

第三方微信登入 | 靜默授權與網頁授權的實現

一:介紹

第三方登入有QQ、微信、微博、支付寶等等,如果現在自己的專案中實現這些登入,即可以使用友盟的sdk,也可以一個一個接入,各有各的有點,這裡不做贅述。

今天和大家分享的是,在專案中實現微信登入,雖然微信官網給出了接入文件,但是我在接入的過程中,遇到一些問題,在此做出總結以便大家參考。主要講微信snsapi_base靜默授權與snsapi_userinfo網頁授權的實現。

二:準備工作

移動應用微信登入是基於OAuth2.0標準協議構建的微信OAuth2.0授權登入系統。

在進行微信OAuth2.0授權登入接入之前,需要完成一下工作才可以開始介接入:

  1. 在微信開放平臺註冊開發者帳號;
  2. 擁有一個已稽核通過的移動應用;
  3. 並獲得相應的AppID和AppSecret;
  4. 申請微信登入且通過稽核。

三:授權流程

微信OAuth2.0授權登入目前支援authorization_code模式,適用於擁有server端的應用授權。該模式整體流程為:

  1. 第三方發起微信授權登入請求,微信使用者允許授權第三方應用後,微信會拉起應用或重定向到第三方網站,並且帶上授權臨時票據code引數;
  2. 通過code引數加上AppID和AppSecret等,通過API換取access_token;
  3. 通過access_token進行介面呼叫,獲取使用者基本資料資源或幫助使用者實現基本操作。

獲取access_token時序圖:

h.png

四:靜默授權與網頁授權的實現

1. 靜默授權與網頁授權的區別

網頁授權:

req.scope = @"snsapi_userinfo";

靜默授權:

req.scope = @"snsapi_base";

snsapi_base與snsapi_userinfo屬於微信網頁授權獲取使用者資訊的兩種作用域:

snsapi_base只能獲取access_token和openID

snsapi_userinfo可以獲取更詳細的使用者資料,比如頭像、暱稱、性別等

2. 獲取CODE

再登入按鈕的點選事件中寫入一下程式碼:

    //構造SendAuthReq結構體
SendAuthReq* req =[[[SendAuthReq alloc]init]autorelease]; req.scope = @"snsapi_userinfo"; req.state = @"123"; //第三方向微信終端傳送一個SendAuthReq訊息結構 [WXApi sendReq:req];

在AppDelegate的didFinishLaunchingWithOptions方法中註冊:

[WXApi registerApp:@"wx1234567890"];

“wx1234567890”為appid,請更換為自己專案的appid

拉起微信開啟授權登入頁如下圖:

點選確認登陸,授權後回撥 WXApiDelegate

-(void)onResp:(BaseReq *)resp
{
    /*
     ErrCode ERR_OK = 0(使用者同意)
     ERR_AUTH_DENIED = -4(使用者拒絕授權)
     ERR_USER_CANCEL = -2(使用者取消)
     code    使用者換取access_token的code,僅在ErrCode為0時有效
     state   第三方程式傳送時用來標識其請求的唯一性的標誌,由第三方程式呼叫sendReq時傳入,由微信終端回傳,state字串長度不能超過1K
     lang    微信客戶端當前語言
     country 微信使用者當前國家資訊
     */

    if ([resp isKindOfClass:[SendAuthResp class]]) //判斷是否為授權請求,否則與微信支付等功能發生衝突
    {
        SendAuthResp *aresp = (SendAuthResp *)resp;
        if (aresp.errCode== 0)
        {
            NSLog(@"code %@",aresp.code);
            [[NSNotificationCenter defaultCenter] postNotificationName:@"wechatDidLoginNotification" object:self userInfo:@{@"code":aresp.code}];
        }
    }
}

使用通知,將aresp.code傳遞到登入頁面

3. 通過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授權時,才會出現該欄位

4. 注意:

  1. 建議將Appsecret、使用者資料(如access_token)放在App雲端伺服器,由雲端中轉介面呼叫請求:

    • Appsecret 是應用介面使用金鑰,洩漏後將可能導致應用資料洩漏、應用的使用者資料洩漏等高風險後果;儲存在客戶端,極有可能被惡意竊取(如反編譯獲取Appsecret);

    • access_token 為使用者授權第三方應用發起介面呼叫的憑證(相當於使用者登入態),儲存在客戶端,可能出現惡意獲取access_token 後導致的使用者資料洩漏、使用者微信相關介面功能被惡意發起等行為;

    • refresh_token 為使用者授權第三方應用的長效憑證,僅用於重新整理access_token,但洩漏後相當於access_token 洩漏,風險同上。

    • 網頁授權的access_token在每次獲取openID時一起更新,在介面呼叫頻次限制中為“無上限”;
    • 普通access_token一般限制為2000次/日,需要自己儲存起來並定時更新。

到這裡同時獲得access_token和openid,靜默授權與網頁授權操作都是一樣的。根據官網文件,網頁授權還可以進一步操作,獲取使用者更多詳細資訊。

5. 獲取使用者個人資訊(UnionID機制)

此介面用於獲取使用者個人資訊,開發者可通過OpenID來獲取使用者基本資訊,介面如下:

https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID

引數說明:
* access_token:呼叫憑證
* openid:普通使用者的標識,對當前開發者帳號唯一

正確的Json返回結果:

{
"openid":"OPENID",
"nickname":"NICKNAME",
"sex":1,
"province":"PROVINCE",
"city":"CITY",
"country":"COUNTRY",
"headimgurl": "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0",
"privilege":[
"PRIVILEGE1",
"PRIVILEGE2"
],
"unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL"
}

6. 靜默授權獲取到使用者詳細資料

在第3步通過snsapi_base,同時獲得access_token和openid,

把這裡的access_token和openid用於下面介面中:

https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN 

引數說明:
* access_token:呼叫憑證
* openid:普通使用者的標識,對當前開發者帳號唯一
* lang:國家地區語言版本,zh_CN 簡體,zh_TW 繁體,en 英語,預設為zh-CN

Json返回結果和snsapi_userinfo下獲取的使用者詳情一樣。

但是這個方法的前提是同一個公眾號內,使用者關注了,如果是其他公眾號,還是需要使用者點選授權的。

希望可以幫助大家,如有問題可加QQ技術交流群: 668562416
如果哪裡有什麼不對或者不足的地方,還望讀者多多提意見或建議

如需轉載請聯絡我,經過授權方可轉載,謝謝

本篇已同步到個人部落格:FBY展菲

歡迎關注我的公眾號:網羅開發