在計算機身份認(rèn)證中是令牌(臨時)的意思捧灰。
APP登錄的時候發(fā)送加密的用戶名和密碼到服務(wù)器,服務(wù)器驗證用戶名和密碼溪窒,如果成功闲擦,以某種方式比如隨機生成32位的字符串作為token,存儲到服務(wù)器中纷妆,并返回token到APP
private void login(final String userName, final String password, String token, String refreshToken, String sdkToken) {
//請求網(wǎng)絡(luò)登錄
final long timeForLogin = System.currentTimeMillis();
Timber.d("start login at " + timeForLogin);
NetManager.getInstance().Login(
new NetManager.Listener<LoginRsp>() {
@Override
public void onResponse(LoginRsp rsp) {
Timber.i("login success rsp:" + rsp);
Timber.w("notifyLoginSuccess Login cost " + (System.currentTimeMillis() - timeForLogin) + "ms");
//獲取登錄態(tài)并存儲
handlerLoginRsp(rsp);
}
@Override
public void onErrorResponse(String msg, int code) {
Timber.e("login error:" + msg + "," + code);
notifyLoginFailed(msg, code);
setAccountInfoBean(null);
}
}, userName, Check.isNotEmpty(password) ? MD5Utils.getMD5ofStr(password) : "", token, refreshToken, sdkToken);
}
登錄接口調(diào)用成功后會返回一個token字符串給APP盔几,APP將它保存在數(shù)據(jù)庫中。
帶有token的回包
在網(wǎng)絡(luò)層面上token明文傳輸?shù)脑挄浅5奈kU掩幢,所以建議一定要使用HTTPS逊拍,并且把token放在post body里。我們項目這里使用的是thrift協(xié)議际邻,協(xié)議的請求包和響應(yīng)包都是需要加密的芯丧。
public byte[] getRequest(int requestId) {
Timber.d("getRequest:" + getRequestName());
report.startSend(getRequestName());
Request request = new Request();
request.header = makeHeader(requestId);
request.body = getRequestBody(requestData);
//打包request
byte[] origins = RequestUtil.encode(request).array();
//加密
byte[] encrys = bEncyption ? EncryptionManager.getEncyption().encryption(origins) : origins;
//加協(xié)議頭
byte[] wraps = bWrapHead ? RequestUtil.wrapHead(encrys) : encrys;
return wraps;
}```
APP拿到token以后請求時,凡是需要驗證的地方都要帶上該token世曾,然后服務(wù)器端驗證token缨恒,成功返回所需要的結(jié)果,失敗返回錯誤信息,讓他重新登錄骗露。其中服務(wù)器上的token設(shè)置一個有效期岭佳,APP請求時驗證token同時驗證有效期,過期也需要重新登錄萧锉。我們項目中珊随,每一個網(wǎng)絡(luò)請求都會帶上token。
public Header makeHeader(int requestId) {
Header header = new Header();
……
header.version = NetConfig.THRIFT_VERSION;
header.token = AccountManager.getInstance().getToken();
header.refresh_token = AccountManager.getInstance().getRefreshToken();
header.accountName = AccountManager.getInstance().getAccountName();
……
return header;
}
當(dāng)服務(wù)器檢測到APP攜帶的token錯誤或者過期了柿隙,會返回錯誤玫恳。APP接受到相應(yīng)的錯誤后,提示用戶重新登錄优俘。
public void onErrorAction() {
……
if (retCode == RetCode.RetCode_CheckToken_Error
|| retCode == RetCode.RetCode_Login_Expire) {
// 彈出登錄態(tài)過期的對話框,讓用戶重新登錄
UIUtils.showLoginExpireDialog();
}
}