token機制完成登錄狀態保持/身份認證

分類:技術 時間:2016-10-25

前言

一般APP都是剛安裝后,第一次啟動時需要登錄(提示你需要登錄或者直接啟動在登錄界面)。而只要登錄成功后,以后每次啟動時都是登錄狀態,不需要每次啟動時再次登錄。不過,也有些APP若你長期未啟動,再次啟動時,它會提示你登錄過期,讓你重新登錄。這個是怎么實現的?APP是怎么保持登錄狀態的?

之所以突然寫這個話題,是因為昨晚無意間刷知乎刷到了這個問題 iOS系統如何實現app登錄類似微信只需登錄一次,退出后不需要每次登錄?

回答里給出了好幾種解決方案,其中比較標準的方案是 “帶時效檢測的token機制” 。所謂 token ,即“令牌”的意思。那這個token機制的執行邏輯是怎么樣的呢?

token機制

token機制的執行邏輯可以用下面一張圖展示清楚:

flowsheet.JPG

當用戶剛安裝完APP,并進行了注冊,擁有了賬號和密碼后。此時,則該進行首次登錄了:

APP將用戶輸入的賬號和密碼提交給服務器;

服務器對其進行校驗,若賬號和密碼對得上則校驗通過,說明登錄成功。并生成一個 token 值,將其保存在數據庫,同時也返回給客戶端;

客戶端拿到返回的 token 值后,可將其保存在本地。作為公共參數,即以后每次請求服務器時都攜帶該 token ,提交給服務器,讓服務器校驗。

服務器接收到請求后,會取出請求頭里的 token 值與數據庫存儲的 token 進行對比校驗。若兩個 token 值相同,則說明用戶登錄成功過,且當前正處于登錄狀態,此時正常返回數據,讓APP顯示數據。若兩個值不一致,則說明原來的的登錄已經失效,此時返回錯誤狀態碼,提示用戶跳轉至登錄界面重新登錄。

用戶每進行一次登錄,登錄成功后服務器都會更新個 token 新值返回給客戶端。

基本的邏輯原理就是這些,下面我們看看項目代碼中具體是怎么寫的。

代碼

首先看在登錄界面發送登錄請求那塊。一開始我以為服務器返回的 token 值會在響應數據體中,也就是和用戶信息在一起。但是我看了接口,并沒有發現與 token 對應的字段。后來仔細看了下代碼,原來 token 是在響應頭中的。上面邏輯里的無論是存儲 token 值,還是攜帶 token 作為公共參數,都是在網絡層完成的。這一切都發生在網絡層,而不麻煩業務層,這很優雅。

每當登錄成功后,服務器在響應頭中返回新的 token 值,將其保存在本地:

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {

    _httpResponse = (NSHTTPURLResponse *)response;
    if(_httpResponse amp;amp; [_httpResponse respondsToSelector:@selector(allHeaderFields)])
    {    
        NSDictionary *httpResponseHeaderFields = [_httpResponse allHeaderFields];
        NSNumber *totle=[NSNumber numberWithLongLong:[[httpResponseHeaderFields objectForKey:@quot;Content-Lengthquot;] longLongValue]];
        _dataSize=[totle integerValue];

        if (_requestInterface == RequestInterfaceLogin ||_requestInterface == RequestInterfaceVerifyCodeLogin ||  _requestInterface == RequestInterfaceRegister) {//設置token
            NSString *tokenString = httpResponseHeaderFields[@quot;x-auth-tokenquot;];
            [REDUserModel saveToken:tokenString];

            RUNDUG(@quot;token------%@quot;,tokenString);
        }
    }
}
  (void)saveToken:(NSString *)token
{
    if (token.length == 0) {
        return;
    }
    [[NSUserDefaults standardUserDefaults]setObject:token forKey:kTokenKey];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

除了在成功登錄的回調方法里存儲 token 值外,也可以在內存和磁盤存儲一個登錄狀態,表示是否是登錄狀態。下次啟動APP時,我只需要從本地獲取該值,看其是登錄狀態否?然后決定界面怎么顯示,或者點擊界面上的按鈕去執行什么事件,是去完成業務動作,還是彈出登錄界面讓用戶重新登錄。

(這個可以寫在網絡層的回調方法里,也可以寫在業務層的回調方法里,都沒問題。)

[REDUserModel shareInstance].isLogin = YES;

    [[NSUserDefaults standardUserDefaults] setBool:YES forKey:kUserLoginStatus];
    [[NSUserDefaults standardUserDefaults] synchronize];

在每次發送非登錄請求接口時,將 token 作為公共參數放入請求頭中提交給服務器,服務器對其進行校驗,判斷是登錄狀態否?還是太久未登錄需要重新登錄。然后返回相應的狀態碼。

if (interface != RequestInterfaceLogin) {
        [_request setValue:[REDUserModel shareInstance].token forHTTPHeaderField:@quot;x-auth-tokenquot;];
    }

結尾

總結,用 token 機制完成登錄狀態保持/身份認證,生成怎樣的 token ,怎么進行 token 校驗都是服務器完成的。其實客戶端的工作很簡單,就是保存服務器給的 token ,然后將其作為請求服務器的公共參數。


Tags: iOS開發

文章來源:http://www.jianshu.com/p/8d28e60af440


ads
ads

相關文章
ads

相關文章

ad