第三方微信登錄 | 靜默授權(quán)與網(wǎng)頁授權(quán)的實(shí)現(xiàn)

一:介紹

第三方登錄有QQ、微信、微博、支付寶等等,如果現(xiàn)在自己的項(xiàng)目中實(shí)現(xiàn)這些登錄,即可以使用友盟的sdk,也可以一個一個接入,各有各的有點(diǎn),這里不做贅述。

今天和大家分享的是,在項(xiàng)目中實(shí)現(xiàn)微信登錄,雖然微信官網(wǎng)給出了接入文檔,但是我在接入的過程中,遇到一些問題,在此做出總結(jié)以便大家參考。主要講微信snsapi_base靜默授權(quán)與snsapi_userinfo網(wǎng)頁授權(quán)的實(shí)現(xiàn)。

二:準(zhǔn)備工作

移動應(yīng)用微信登錄是基于OAuth2.0標(biāo)準(zhǔn)協(xié)議構(gòu)建的微信OAuth2.0授權(quán)登錄系統(tǒng)。

在進(jìn)行微信OAuth2.0授權(quán)登錄接入之前,需要完成一下工作才可以開始介接入:

  1. 在微信開放平臺注冊開發(fā)者帳號;
  2. 擁有一個已審核通過的移動應(yīng)用;
  3. 并獲得相應(yīng)的AppID和AppSecret;
  4. 申請微信登錄且通過審核。

三:授權(quán)流程

微信OAuth2.0授權(quán)登錄目前支持authorization_code模式,適用于擁有server端的應(yīng)用授權(quán)。該模式整體流程為:

  1. 第三方發(fā)起微信授權(quán)登錄請求,微信用戶允許授權(quán)第三方應(yīng)用后,微信會拉起應(yīng)用或重定向到第三方網(wǎng)站,并且?guī)鲜跈?quán)臨時票據(jù)code參數(shù);
  2. 通過code參數(shù)加上AppID和AppSecret等,通過API換取access_token;
  3. 通過access_token進(jìn)行接口調(diào)用,獲取用戶基本數(shù)據(jù)資源或幫助用戶實(shí)現(xiàn)基本操作。

獲取access_token時序圖:

h.png

四:靜默授權(quán)與網(wǎng)頁授權(quán)的實(shí)現(xiàn)

1. 靜默授權(quán)與網(wǎng)頁授權(quán)的區(qū)別

網(wǎng)頁授權(quán):

req.scope = @"snsapi_userinfo";

靜默授權(quán):

req.scope = @"snsapi_base";

snsapi_base與snsapi_userinfo屬于微信網(wǎng)頁授權(quán)獲取用戶信息的兩種作用域:

snsapi_base只能獲取access_token和openID

snsapi_userinfo可以獲取更詳細(xì)的用戶資料,比如頭像、昵稱、性別等

2. 獲取CODE

再登錄按鈕的點(diǎn)擊事件中寫入一下代碼:

    //構(gòu)造SendAuthReq結(jié)構(gòu)體
    SendAuthReq* req =[[[SendAuthReq alloc]init]autorelease];
    req.scope = @"snsapi_userinfo";
    req.state = @"123";
    //第三方向微信終端發(fā)送一個SendAuthReq消息結(jié)構(gòu)
    [WXApi sendReq:req];

在AppDelegate的didFinishLaunchingWithOptions方法中注冊:

[WXApi registerApp:@"wx1234567890"];

"wx1234567890"為appid,請更換為自己項(xiàng)目的appid

拉起微信打開授權(quán)登錄頁如下圖:

點(diǎn)擊確認(rèn)登陸,授權(quán)后回調(diào) WXApiDelegate

-(void)onResp:(BaseReq *)resp
{
    /*
     ErrCode ERR_OK = 0(用戶同意)
     ERR_AUTH_DENIED = -4(用戶拒絕授權(quán))
     ERR_USER_CANCEL = -2(用戶取消)
     code    用戶換取access_token的code,僅在ErrCode為0時有效
     state   第三方程序發(fā)送時用來標(biāo)識其請求的唯一性的標(biāo)志,由第三方程序調(diào)用sendReq時傳入,由微信終端回傳,state字符串長度不能超過1K
     lang    微信客戶端當(dāng)前語言
     country 微信用戶當(dāng)前國家信息
     */
    
    if ([resp isKindOfClass:[SendAuthResp class]]) //判斷是否為授權(quán)請求,否則與微信支付等功能發(fā)生沖突
    {
        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

參數(shù)說明:

  • appid:應(yīng)用唯一標(biāo)識,在微信開放平臺提交應(yīng)用審核通過后獲得
  • secret:應(yīng)用密鑰AppSecret,在微信開放平臺提交應(yīng)用審核通過后獲得
  • code:填寫第一步獲取的code參數(shù)
  • grant_type:填authorization_code

網(wǎng)絡(luò)請求返回的參數(shù)格式如下:

{ 
"access_token":"ACCESS_TOKEN", 
"expires_in":7200, 
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID", 
"scope":"SCOPE",
"unionid":"o6_bmasdasdsad6_2sgVt7hMZOPfL"
}

參數(shù)說明:

  • access_token:接口調(diào)用憑證
  • expires_in:access_token接口調(diào)用憑證超時時間,單位(秒)
  • refresh_token:用戶刷新access_token
  • openid:授權(quán)用戶唯一標(biāo)識
  • scope:用戶授權(quán)的作用域,使用逗號(,)分隔
  • unionid:當(dāng)且僅當(dāng)該移動應(yīng)用已獲得該用戶的userinfo授權(quán)時,才會出現(xiàn)該字段

4. 注意:

  1. 建議將Appsecret、用戶數(shù)據(jù)(如access_token)放在App云端服務(wù)器,由云端中轉(zhuǎn)接口調(diào)用請求:
  • Appsecret 是應(yīng)用接口使用密鑰,泄漏后將可能導(dǎo)致應(yīng)用數(shù)據(jù)泄漏、應(yīng)用的用戶數(shù)據(jù)泄漏等高風(fēng)險后果;存儲在客戶端,極有可能被惡意竊取(如反編譯獲取Appsecret);

  • access_token 為用戶授權(quán)第三方應(yīng)用發(fā)起接口調(diào)用的憑證(相當(dāng)于用戶登錄態(tài)),存儲在客戶端,可能出現(xiàn)惡意獲取access_token 后導(dǎo)致的用戶數(shù)據(jù)泄漏、用戶微信相關(guān)接口功能被惡意發(fā)起等行為;

  • refresh_token 為用戶授權(quán)第三方應(yīng)用的長效憑證,僅用于刷新access_token,但泄漏后相當(dāng)于access_token 泄漏,風(fēng)險同上。

  1. 要注意網(wǎng)絡(luò)授權(quán)網(wǎng)頁授權(quán)access_token普通access_token的區(qū)別:
  • 網(wǎng)頁授權(quán)的access_token在每次獲取openID時一起更新,在接口調(diào)用頻次限制中為“無上限”;
  • 普通access_token一般限制為2000次/日,需要自己保存起來并定時更新。

到這里同時獲得access_token和openid,靜默授權(quán)與網(wǎng)頁授權(quán)操作都是一樣的。根據(jù)官網(wǎng)文檔,網(wǎng)頁授權(quán)還可以進(jìn)一步操作,獲取用戶更多詳細(xì)信息。

5. 獲取用戶個人信息(UnionID機(jī)制)

此接口用于獲取用戶個人信息,開發(fā)者可通過OpenID來獲取用戶基本信息,接口如下:

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

參數(shù)說明:

  • access_token:調(diào)用憑證
  • openid:普通用戶的標(biāo)識,對當(dāng)前開發(fā)者帳號唯一

正確的Json返回結(jié)果:

{
"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. 靜默授權(quán)獲取到用戶詳細(xì)資料

在第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 

參數(shù)說明:

  • access_token:調(diào)用憑證
  • openid:普通用戶的標(biāo)識,對當(dāng)前開發(fā)者帳號唯一
  • lang:國家地區(qū)語言版本,zh_CN 簡體,zh_TW 繁體,en 英語,默認(rèn)為zh-CN

Json返回結(jié)果和snsapi_userinfo下獲取的用戶詳情一樣。

但是這個方法的前提是同一個公眾號內(nèi),用戶關(guān)注了,如果是其他公眾號,還是需要用戶點(diǎn)擊授權(quán)的。

希望可以幫助大家
如果哪里有什么不對或者不足的地方,還望讀者多多提意見或建議
如需轉(zhuǎn)載請聯(lián)系我,經(jīng)過授權(quán)方可轉(zhuǎn)載,謝謝
關(guān)注【網(wǎng)羅開發(fā)】公眾號,領(lǐng)資源

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容