今天項目中集成微信登錄潜沦,以為非常順利的事情,卻還是多多少少出現(xiàn)了一些問題稼跳。所以記錄一下集成過程中出現(xiàn)的問題录煤。
開發(fā)環(huán)境:
[x] 系統(tǒng)環(huán)境:
windows10
[x] AndroidStudio 版本:
3.3.2
[x] Gradle 版本:
4.10.1
集成過程(參照微信接入指南(https://open.weixin.qq.com/cgibin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=1417751808&token=60cf535dd0331502a793d5f32051b033b24b9e9d&lang=zh_CN))
- 在項目gradle添加依賴
//微信
implementation 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'
2.注冊申請好的AppId到微信(必須在調(diào)用登錄功能之前)
// APP_ID
private static final String APP_ID = "自己的appId";
api = WXAPIFactory.createWXAPI(context, APP_ID, true);
// 將應(yīng)用的appId注冊到微信
api.registerApp(APP_ID);
3.發(fā)送登錄請求()
SendAuth.Req req = new SendAuth.Req();
req.scope = "snsapi_userinfo";
req.state = "111";
api.sendReq(req);
參數(shù)說明
來源: https://open.weixin.qq.com/cgi-bin/showdocument?action=doc&id=open1419317851&t=0.2650837650069082
參數(shù) | 是否必須 | 說明 |
---|---|---|
appid | 是 | 應(yīng)用唯一標識,在微信開放平臺提交應(yīng)用審核通過后獲得 |
scope | 是 | 應(yīng)用授權(quán)作用域又谋,如獲取用戶個人信息則填寫snsapi_userinfo( 什么是授權(quán)域拼缝? ) |
state | 否 | 用于保持請求和回調(diào)的狀態(tài)娱局,授權(quán)請求后原樣帶回給第三方。該參數(shù)可用于防止csrf攻擊(跨站請求偽造攻擊)咧七,建議第三方帶上該參數(shù)衰齐,可設(shè)置為簡單的隨機數(shù)加session進行校驗 |
4.在項目包名下創(chuàng)建wxapi包并且創(chuàng)建WXEntryActivity,并且在AndroidManifest中配置,配置必須與下圖中一致。
<!--微信回調(diào)-->
<activity
android:name=".wxapi.WXEntryActivity"
android:label="WXEntryActivity"
android:exported="true"
android:launchMode="singleTask"
android:taskAffinity="包名"></activity>
5.在WXEntryActivity中,實現(xiàn) IWXAPIEventHandler 接口继阻。在oncreate方法中注冊回調(diào)
api.handleIntent(getIntent(), this);
如果不注冊,則收不到回調(diào)(我剛開始沒有注冊該回調(diào)耻涛,導(dǎo)致一直收不到回調(diào)信息)。
6.在項目gradle中配置簽名文件,必須與平臺中的簽名一致瘟檩。
android {
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),'proguard-rules.pro'
}
debug{
signingConfig signingConfigs.debug // 配置debug包的簽名
}
}
signingConfigs {
debug {
storeFile file("簽名路徑/debug.keystore")
storePassword "android"
keyAlias "androiddebugkey"
keyPassword "android"
}
}
}
到這里就集成成功了抹缕,我遇到的問題主要是沒有注冊回調(diào),導(dǎo)致收不到信息墨辛。
關(guān)于WXEntryActivity中,實現(xiàn) IWXAPIEventHandler 接口后,根據(jù)微信提供的文檔以及業(yè)務(wù)需要繼續(xù)下去就好了:
@Override
public void onReq(BaseReq baseReq) {
}
@Override
public void onResp(BaseResp baseResp) {
Log.e(TAG, ((SendAuth.Resp) baseResp).code +
"--" + ((SendAuth.Resp) baseResp).url +
"--" + baseResp.getType() +
"--" + baseResp.errCode +
"--" + ((SendAuth.Resp) baseResp).state +
"--" + ((SendAuth.Resp) baseResp).lang);
}
返回說明
用戶點擊授權(quán)后卓研,微信客戶端會被拉起,跳轉(zhuǎn)至授權(quán)界面睹簇,用戶在該界面點擊允許或取消奏赘,SDK通過SendAuth的Resp返回數(shù)據(jù)給調(diào)用方。
返回值 | 說明 |
---|---|
ErrCode | ERR_OK = 0(用戶同意) ERR_AUTH_DENIED = -4(用戶拒絕授權(quán)) ERR_USER_CANCEL = -2(用戶取消) |
code | 用戶換取access_token的code太惠,僅在ErrCode為0時有效 |
state | 第三方程序發(fā)送時用來標識其請求的唯一性的標志磨淌,由第三方程序調(diào)用sendReq時傳入,由微信終端回傳凿渊,state字符串長度不能超過1K |
lang | 微信客戶端當(dāng)前語言 |
country | 微信用戶當(dāng)前國家信息 |
第二步:通過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ù)說明
參數(shù) | 是否必須 | 說明 |
---|---|---|
appid | 是 | 應(yīng)用唯一標識,在微信開放平臺提交應(yīng)用審核通過后獲得 |
secret | 是 | 應(yīng)用密鑰AppSecret埃脏,在微信開放平臺提交應(yīng)用審核通過后獲得 |
code | 是 | 填寫第一步獲取的code參數(shù) |
grant_type | 是 | 填authorization_code |
返回說明
正確的返回:
{ "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)用戶唯一標識 |
scope | 用戶授權(quán)的作用域,使用逗號(,)分隔 |
unionid | 當(dāng)且僅當(dāng)該移動應(yīng)用已獲得該用戶的userinfo授權(quán)時剂癌,才會出現(xiàn)該字段 |
錯誤返回樣例:
{"errcode":40029,"errmsg":"invalid code"}
刷新access_token有效期
access_token是調(diào)用授權(quán)關(guān)系接口的調(diào)用憑證淤翔,由于access_token有效期(目前為2個小時)較短翰绊,當(dāng)access_token超時后佩谷,可以使用refresh_token進行刷新,access_token刷新結(jié)果有兩種:
1\. 若access_token已超時监嗜,那么進行refresh_token會獲取一個新的access_token谐檀,新的超時時間;2\. 若access_token未超時裁奇,那么進行refresh_token不會改變access_token桐猬,但超時時間會刷新,相當(dāng)于續(xù)期access_token刽肠。
refresh_token擁有較長的有效期(30天)溃肪,當(dāng)refresh_token失效的后免胃,需要用戶重新授權(quán)。
請求方法
獲取第一步的code后惫撰,請求以下鏈接進行refresh_token:
https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN
參數(shù)說明
參數(shù) | 是否必須 | 說明 |
---|---|---|
appid | 是 | 應(yīng)用唯一標識 |
grant_type | 是 | 填refresh_token |
refresh_token | 是 | 填寫通過access_token獲取到的refresh_token參數(shù) |
返回說明
正確的返回:
{"access_token":"ACCESS_TOKEN","expires_in":7200,"refresh_token":"REFRESH_TOKEN","openid":"OPENID","scope":"SCOPE"}
參數(shù) | 說明 |
---|---|
access_token | 接口調(diào)用憑證 |
expires_in | access_token接口調(diào)用憑證超時時間羔沙,單位(秒) |
refresh_token | 用戶刷新access_token |
openid | 授權(quán)用戶唯一標識 |
scope | 用戶授權(quán)的作用域,使用逗號(,)分隔 |
錯誤返回樣例:
{"errcode":40030,"errmsg":"invalid refresh_token"}
注意:
1厨钻、Appsecret 是應(yīng)用接口使用密鑰扼雏,泄漏后將可能導(dǎo)致應(yīng)用數(shù)據(jù)泄漏、應(yīng)用的用戶數(shù)據(jù)泄漏等高風(fēng)險后果夯膀;存儲在客戶端诗充,極有可能被惡意竊取(如反編譯獲取Appsecret)诱建;2蝴蜓、access_token 為用戶授權(quán)第三方應(yīng)用發(fā)起接口調(diào)用的憑證(相當(dāng)于用戶登錄態(tài)),存儲在客戶端涂佃,可能出現(xiàn)惡意獲取access_token 后導(dǎo)致的用戶數(shù)據(jù)泄漏励翼、用戶微信相關(guān)接口功能被惡意發(fā)起等行為;3辜荠、refresh_token 為用戶授權(quán)第三方應(yīng)用的長效憑證汽抚,僅用于刷新access_token,但泄漏后相當(dāng)于access_token 泄漏伯病,風(fēng)險同上造烁。
建議將Appsecret、用戶數(shù)據(jù)(如access_token)放在App云端服務(wù)器午笛,由云端中轉(zhuǎn)接口調(diào)用請求惭蟋。
第三步:通過access_token調(diào)用接口
獲取access_token后,進行接口調(diào)用药磺,有以下前提:
- access_token有效且未超時告组;
- 微信用戶已授權(quán)給第三方應(yīng)用帳號相應(yīng)接口作用域(scope)。
對于接口作用域(scope)癌佩,能調(diào)用的接口有以下:
授權(quán)作用域(scope) | 接口 | 接口說明 |
---|---|---|
snsapi_base | /sns/oauth2/access_token | 通過code換取access_token木缝、refresh_token和已授權(quán)scope |
/sns/oauth2/refresh_token | 刷新或續(xù)期access_token使用 | |
/sns/auth | 檢查access_token有效性 | |
snsapi_userinfo | /sns/userinfo | 獲取用戶個人信息 |
其中snsapi_base屬于基礎(chǔ)接口,若應(yīng)用已擁有其它scope權(quán)限围辙,則默認擁有snsapi_base的權(quán)限我碟。使用snsapi_base可以讓移動端網(wǎng)頁授權(quán)繞過跳轉(zhuǎn)授權(quán)登錄頁請求用戶授權(quán)的動作,直接跳轉(zhuǎn)第三方網(wǎng)頁帶上授權(quán)臨時票據(jù)(code)姚建,但會使得用戶已授權(quán)作用域(scope)僅為snsapi_base矫俺,從而導(dǎo)致無法獲取到需要用戶授權(quán)才允許獲得的數(shù)據(jù)和基礎(chǔ)功能。
接口調(diào)用方法可查閱《微信授權(quán)關(guān)系接口調(diào)用指南》
F.A.Q
1. 什么是授權(quán)臨時票據(jù)(code)?
答:第三方通過code進行獲取access_token的時候需要用到厘托,code的超時時間為10分鐘友雳,一個code只能成功換取一次access_token即失效。code的臨時性和一次保障了微信授權(quán)登錄的安全性铅匹。第三方可通過使用https和state參數(shù)沥阱,進一步加強自身授權(quán)登錄的安全性。
2. 什么是授權(quán)作用域(scope)伊群?
答:授權(quán)作用域(scope)代表用戶授權(quán)給第三方的接口權(quán)限考杉,第三方應(yīng)用需要向微信開放平臺申請使用相應(yīng)scope的權(quán)限后,使用文檔所述方式讓用戶進行授權(quán)舰始,經(jīng)過用戶授權(quán)崇棠,獲取到相應(yīng)access_token后方可對接口進行調(diào)用。
3.開放平臺移動應(yīng)用微信登錄目前是否收費丸卷?
答:“微信登錄”和第三方網(wǎng)站共享微信龐大的用戶價值枕稀,同時為微信用戶提供更便捷服務(wù)和更優(yōu)質(zhì)內(nèi)容,實現(xiàn)雙向共贏谜嫉,目前不收取任何費用萎坷。
文章部分內(nèi)容轉(zhuǎn)載微信開放平臺 https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419317851&token=60cf535dd0331502a793d5f32051b033b24b9e9d&lang=zh_CN