一、我們先解釋一下他的含義: 1、Token的引入:Token是在客戶端頻繁向服務端請求數據,服務端頻繁的去資料庫查詢用戶名和密碼併進行對比,判斷用戶名和密碼正確與否,並作出相應提示,在這樣的背景下,Token便應運而生。 2、Token的定義:Token是服務端生成的一串字元串,以作客戶端進行請求 ...
一、我們先解釋一下他的含義:
1、Token的引入:Token是在客戶端頻繁向服務端請求數據,服務端頻繁的去資料庫查詢用戶名和密碼併進行對比,判斷用戶名和密碼正確與否,並作出相應提示,在這樣的背景下,Token便應運而生。
2、Token的定義:Token是服務端生成的一串字元串,以作客戶端進行請求的一個令牌,當第一次登錄後,伺服器生成一個Token便將此Token返回給客戶端,以後客戶端只需帶上這個Token前來請求數據即可,無需再次帶上用戶名和密碼。
3、使用Token的目的:Token的目的是為了減輕伺服器的壓力,減少頻繁的查詢資料庫,使伺服器更加健壯。
二、如何使用Token?。
1、用設備號/設備mac地址作為Token(推薦)
客戶端:客戶端在登錄的時候獲取設備的設備號/mac地址,並將其作為參數傳遞到服務端。
服務端:服務端接收到該參數後,便用一個變數來接收同時將其作為Token保存在資料庫,並將該Token設置到session中,客戶端每次請求的時候都要統一攔截,並將客戶端傳遞的token和伺服器端session中的token進行對比,如果相同則放行,不同則拒絕。
分析:此刻客戶端和伺服器端就統一了一個唯一的標識Token,而且保證了每一個設備擁有了一個唯一的會話。該方法的缺點是客戶端需要帶設備號/mac地址作為參數傳遞,而且伺服器端還需要保存;優點是客戶端不需重新登錄,只要登錄一次以後一直可以使用,至於超時的問題是有伺服器這邊來處理,如何處理?若伺服器的Token超時後,伺服器只需將客戶端傳遞的Token向資料庫中查詢,同時並賦值給變數Token,如此,Token的超時又重新計時。
2、用session值作為Token
客戶端:客戶端只需攜帶用戶名和密碼登陸即可。
客戶端:客戶端接收到用戶名和密碼後並判斷,如果正確了就將本地獲取sessionID作為Token返回給客戶端,客戶端以後只需帶上請求數據即可。
分析:這種方式使用的好處是方便,不用存儲數據,但是缺點就是當session過期後,客戶端必須重新登錄才能進行訪問數據。
三、使用過程中出現的問題以及解決方案?
剛纔我們輕鬆介紹了Token的兩種使用方式,但是在使用過程中我們還出現各種問題,Token第一種方法中我們隱藏了一個在網路不好或者併發請求時會導致多次重覆提交數據的問題。
該問題的解決方案:將session和Token套用,如此便可解決,如何套用呢?請看這段解釋:
這就是解決重覆提交的方案。
/** * 用戶登錄,將私有token保存 * * @param appContext * @param username * @param password * @return GitlabUser用戶信息 * @throws IOException */ public static User login(AppContext appContext, String userEmail, String password) throws AppException { String urlString = URLs.LOGIN_HTTPS; Session session = getHttpRequestor() .init(appContext, HTTPRequestor.POST_METHOD, urlString) .with("email", userEmail) .with("password", password) .to(Session.class); // 保存用戶的私有token if (session != null && session.get_privateToken() != null) { String token = CyptoUtils.encode(GITOSC_PRIVATE_TOKEN, session.get_privateToken()); appContext.setProperty(PRIVATE_TOKEN, token); } return session; }