談?wù)劦谌紸pp接入微信登錄 解讀
接入微信登錄:
1、準(zhǔn)備工作
1.在微信開放平臺https://open.weixin.qq.com/注冊成為開發(fā)者。
2.在“管理中心”中創(chuàng)建一個移動應(yīng)用,需“應(yīng)用名稱、簡介、及28*28和108*108的PNG圖片各一張,且大小不超過300k”,點(diǎn)擊下一步,需“應(yīng)用官網(wǎng)地址,應(yīng)用簽名及包名”等信息,然后即可提交審核。
說明:
應(yīng)用簽名:可在微信開發(fā)平臺的資源中心》》資源下載》》中下載“簽名生成工具”,用戶獲取已經(jīng)安裝到手機(jī)的第三方應(yīng)用的簽名。輸入應(yīng)用包名,即可獲得該應(yīng)用的簽名值。
3.提交審核后,在7個工作日內(nèi)騰訊將給出審核結(jié)果。(通常較快,幾個小時就可反饋結(jié)果)
2、微信登錄接入
微信登錄遵循協(xié)議Aouth2.0中的授權(quán)碼模式,先介紹一下Aouth2.0的流程:

3、微信登錄的官方文檔將微信登錄分為3個步驟:
第一步.請求code:
{
// send oauth request
Final SendAuth.Req req = new SendAuth.Req();
req.scope = "snsapi_userinfo";
req.state = "wechat_sdk_demo_test";
api.sendReq(req);
}
用這段代碼向微信開放平臺請求授權(quán)碼code,可拉起微信并打開授權(quán)登錄頁(前提是你安裝了微信應(yīng)用并已登錄,未登錄的會引導(dǎo)你先登錄)下圖:

需要注意的情況:
1.如果微信授權(quán)頁不顯示,請檢查你的APP簽名是否和你在騰訊開放平臺的APP簽名一致,不一致可修改騰訊開放平臺中的APP簽名,修改后重裝微信或清除微信數(shù)據(jù)后重試。
2.在你的包名相應(yīng)目錄下新建一個wxapi目錄,并在該wxapi目錄下新增一個WXEntryActivity類,該類繼承自Activity(例如應(yīng)用程序的包名為net.sourceforge,則新的包名為:net.sourceforge.wxapi),此處應(yīng)注意包名不要弄錯,新增類的名字必須為WXEntryActivity。
返回說明
用戶點(diǎn)擊授權(quán)后,微信客戶端會被拉起,跳轉(zhuǎn)至授權(quán)界面,用戶在該界面點(diǎn)擊允許或取消,SDK通過SendAuth的Resp返回數(shù)據(jù)給調(diào)用方?;卣{(diào)WXEntryActivity中的onResp(BaseResp resp)方法,如下:
@Override
public void onResp(BaseResp resp) {
int errorCode = resp.errCode;
switch (errorCode) {
case BaseResp.ErrCode.ERR_OK:
//用戶同意
String code = ((SendAuth.Resp) resp).code;
break;
case BaseResp.ErrCode.ERR_AUTH_DENIED:
//用戶拒絕
break;
case BaseResp.ErrCode.ERR_USER_CANCEL:
//用戶取消
break;
default:
break;
}
ToastUtil.showMessageLong(this, resp.errStr);
}
客戶端收到授權(quán)碼后,向自己的服務(wù)器發(fā)起登錄請求,并附帶收到的授權(quán)碼。
服務(wù)端收到登錄請求,向微信開放平臺請求獲取access_token,微信開放平臺返回Json字符串:
第二步:通過code獲取access_token:
獲取第一步的code后,請求以下鏈接獲取access_token:
private String getAccessToken(String code) {
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
URI uri = URI.create(url);
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(uri);
HttpResponse response;
try {
response = client.execute(get);
if (response.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = response.getEntity();
BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"));
StringBuilder sb = new StringBuilder();
for (String temp = reader.readLine(); temp != null; temp = reader.readLine()) {
sb.append(temp);
}
JSONObject object = new JSONObject(sb.toString().trim());
accessToken = object.getString("access_token");
openID = object.getString("openid");
refreshToken = object.getString("refresh_token");
expires_in = object.getLong("expires_in");
return accessToken;
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
參數(shù)說明
參數(shù) 是否必須 說明
appid 是 應(yīng)用唯一標(biāo)識,在微信開放平臺提交應(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)用戶唯一標(biāo)識
scope 用戶授權(quán)的作用域,使用逗號(,)分隔
unionid 只有在用戶將公眾號綁定到微信開放平臺帳號后,才會出現(xiàn)該字段。
錯誤返回樣例:
{"errcode":40029,"errmsg":"invalid code"}
第三步:通過access_token調(diào)用接口
獲取access_token后,進(jìn)行接口調(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)限,則默認(rè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ǔ)功能。
以獲取用戶信息為例:
private void getUserInfo() {
if (isAccessTokenIsInvalid() && System.currentTimeMillis() < expires_in) {
String uri = "https://api.weixin.qq.com/sns/userinfo?access_token=" + accessToken + "&openid=" + openID;
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(URI.create(uri));
try {
HttpResponse response = client.execute(get);
if (response.getStatusLine().getStatusCode() == 200) {
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
StringBuilder builder = new StringBuilder();
for (String temp = reader.readLine(); temp != null; temp = reader.readLine()) {
builder.append(temp);
}
JSONObject object = new JSONObject(builder.toString().trim());
String nikeName = object.getString("nickname");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
微信重復(fù)登錄
假設(shè)用戶已經(jīng)獲得授權(quán),則下次登錄時只需要驗證access_token是否有效,無效則重新獲取授權(quán),有效則無需重新獲得授權(quán)。
1.用戶向自己的服務(wù)器請求登錄,登錄方式為微信登錄,附帶上次登錄返回的的access_token
2.服務(wù)器收到用戶的登錄請求,向微信開放平臺發(fā)送access_token是否有效的驗證請求如下:
private boolean isAccessTokenIsInvalid() {
String url = "https://api.weixin.qq.com/sns/auth?access_token=" + accessToken + "&openid=" + openID;
URI uri = URI.create(url);
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(uri);
HttpResponse response;
try {
response = client.execute(get);
if (response.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = response.getEntity();
BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"));
StringBuilder sb = new StringBuilder();
for (String temp = reader.readLine(); temp != null; temp = reader.readLine()) {
sb.append(temp);
}
JSONObject object = new JSONObject(sb.toString().trim());
int errorCode = object.getInt("errcode");
if (errorCode == 0) {
return true;
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
返回說明
正確的Json返回結(jié)果:
{
"errcode":0,"errmsg":"ok"
}
錯誤的Json返回示例:
{
"errcode":40003,"errmsg":"invalid openid"
}
如果access_token有效,服務(wù)端將信息返回給客戶端,客戶端成功登錄。
如果access_token無效,服務(wù)端向微信開放平臺發(fā)送刷新access_token的請求如下:
access_token是調(diào)用授權(quán)關(guān)系接口的調(diào)用憑證,由于access_token有效期(目前為2個小時)較短,當(dāng)access_token超時后,可以使用refresh_token進(jìn)行刷新,access_token刷新結(jié)果有兩種:
1.若access_token已超時,那么進(jìn)行refresh_token會獲取一個新的access_token,新的超時時間;
2.若access_token未超時,那么進(jìn)行refresh_token不會改變access_token,但超時時間會刷新,相當(dāng)于續(xù)期access_token。
刷新token
private void refreshAccessToken() {
String uri = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=" + ShareUtil.APP_ID + "&grant_type=refresh_token&refresh_token="
+ refreshToken;
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(URI.create(uri));
try {
HttpResponse response = client.execute(get);
if (response.getStatusLine().getStatusCode() == 200) {
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
StringBuilder builder = new StringBuilder();
for (String temp = reader.readLine(); temp != null; temp = reader.readLine()) {
builder.append(temp);
}
JSONObject object = new JSONObject(builder.toString().trim());
accessToken = object.getString("access_token");
refreshToken = object.getString("refresh_token");
openID = object.getString("openid");
expires_in = object.getLong("expires_in");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
正確的返回:
{
"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)用戶唯一標(biāo)識
scope 用戶授權(quán)的作用域,使用逗號(,)分隔
錯誤返回樣例:
{
"errcode":40030,"errmsg":"invalid refresh_token"
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
JavaScript實(shí)現(xiàn)存儲HTML字符串示例
這篇文章主要介紹了JavaScript存儲HTML字符串的具體實(shí)現(xiàn),需要的朋友可以參考下2014-04-04
實(shí)現(xiàn)web打印的各種方法介紹及實(shí)現(xiàn)代碼
web的打印方法具我自己懂得知道的有:JQuery插件Jqprint實(shí)現(xiàn);JQery打印插件PrintArea實(shí)現(xiàn)網(wǎng)頁打印;CSS控制網(wǎng)頁打印樣式,本文詳細(xì)介紹實(shí)現(xiàn)步驟,感興趣的朋友可以了解下2013-01-01

