田紹東 徐萬明
摘要:Android是當前主流移動設(shè)備操作系統(tǒng)之一,基于Android系統(tǒng)的軟件也非常多,但Android系統(tǒng)上的軟件直接訪問網(wǎng)絡(luò)數(shù)據(jù)庫有一定的風險,該文對Android軟件訪問網(wǎng)絡(luò)數(shù)據(jù)庫技術(shù)進行研究,提出兩種更安全的Android訪問網(wǎng)絡(luò)數(shù)據(jù)庫代理技術(shù)。
關(guān)鍵詞:Android;網(wǎng)絡(luò)數(shù)據(jù)庫;遠程訪問
中圖分類號:TP311 文獻標識碼:A 文章編號:1009-3044(2018)03-0014-02
目前基于Android系統(tǒng)的手機在市場占據(jù)較大的份額。據(jù)CodeForge網(wǎng)站發(fā)布2016年上半年《中國程序員調(diào)查報告》中顯示:在移動端市場,程序員們使用Android系統(tǒng)所占比例為79%,使用IOS系統(tǒng)的所占比例為18% 。Android系統(tǒng)下手機軟件大多數(shù)都要與網(wǎng)絡(luò)數(shù)據(jù)庫進行交互,從而實現(xiàn)軟件相關(guān)功能。但是當下基于Android環(huán)境下直接連接、訪問網(wǎng)絡(luò)數(shù)據(jù)庫的技術(shù)并不安全。因此研究Android環(huán)境下如何安全地訪問網(wǎng)絡(luò)數(shù)據(jù)庫的技術(shù)具有重要意義。
1 Android直接連接網(wǎng)絡(luò)數(shù)據(jù)的風險
相信許多Android程序員都知道在Android環(huán)境下連接數(shù)據(jù)的技術(shù),簡單方式是使用JDBC(Java Database Connectivity,java數(shù)據(jù)庫連接)來連接數(shù)據(jù)庫。
JDBC是一種用于執(zhí)行SQL語句的Java API,可以為多種關(guān)系數(shù)據(jù)庫提供統(tǒng)一訪問,它由一組用Java語言編寫的類和接口組成。JDBC提供了一種基準,據(jù)此可以構(gòu)建更高級的工具和接口,使數(shù)據(jù)庫開發(fā)人員能夠編寫數(shù)據(jù)庫應(yīng)用程序[1]。
我們來見識一下使用JDBC連接數(shù)據(jù)的關(guān)鍵部分的代碼,以連接SQL數(shù)據(jù)庫為例。
Connection conn = DriverManager.getConnection
("jdbc:microsoft:sqlserver://host:port; DatabaseName=database","user","pwd");
上述代碼是通過Connection接口連接SQL數(shù)據(jù)庫,并在連接上傳送SQL指令,以實現(xiàn)相關(guān)數(shù)據(jù)庫操縱功能。分析getConnection方法中的參數(shù),容易知道這里包含了訪問數(shù)據(jù)的類型,數(shù)據(jù)庫服務(wù)器的IP,端口號,數(shù)據(jù)庫名,訪問數(shù)據(jù)用戶名,訪問數(shù)據(jù)用戶的密碼等信息。那么如果這些信息被別有用心的人知道了會有什么后果?這就是Android直接連接網(wǎng)絡(luò)數(shù)據(jù)的風險!它可能暴露數(shù)據(jù)庫訪問的重要信息,可能帶來非常嚴重的后果。我們想想為什么支付寶、微信、電信翼支付等只給程序員編程的支付接口?而不是如上的訪問數(shù)據(jù)庫的方式。
2 代理訪問網(wǎng)絡(luò)數(shù)據(jù)技術(shù)
研究Android環(huán)境下訪問網(wǎng)絡(luò)數(shù)據(jù)庫的人員很多,他們結(jié)合前人的智慧提出了一些較好的訪問網(wǎng)絡(luò)數(shù)據(jù)庫的方法,如彭鳳凌提出了使用消息的模塊化交互結(jié)構(gòu)系統(tǒng)來實現(xiàn)Android手機與遠程數(shù)據(jù)庫的交互[2];田佳影在文章中寫道使用Servlet進行數(shù)據(jù)交互,結(jié)合HttpClient組建來傳送數(shù)據(jù),進而實現(xiàn)Android訪問遠程數(shù)據(jù)庫[3]。龔成瑩在其論文中提到Android遠程數(shù)據(jù)庫使用JSON格式交互信息的方便性[4]。徐萬明等提出了通過WebService實現(xiàn)了Android系統(tǒng)訪問SQLServer數(shù)據(jù)庫的例子[5]。
本人結(jié)合某Android項目研發(fā),提出兩種安全訪問網(wǎng)絡(luò)數(shù)據(jù)庫的方法。
2.1 使用JSON數(shù)據(jù)格式與ASPX網(wǎng)頁交互操作訪問數(shù)據(jù)庫
在某Android項目研發(fā)過程中,考慮到安全性不能使用JDBC與數(shù)據(jù)庫直接連接進行數(shù)據(jù)操縱,在Android程序中通過httpClient對象與ASPX網(wǎng)頁進行數(shù)據(jù)交互,實現(xiàn)網(wǎng)絡(luò)數(shù)據(jù)交換,實現(xiàn)通過ASPX網(wǎng)頁代理訪問數(shù)據(jù)庫。本方法的產(chǎn)生是源于AJAX訪問ASPX網(wǎng)頁的技術(shù)。
下面將用戶登錄驗證模塊當示例展示通過ASPX網(wǎng)頁代理訪問數(shù)據(jù)庫的大致過程。Android端軟件設(shè)計主要過程如下:
第一步:建立httpClient;
HttpClienthttpClient = new DefaultHttpClient();
第二步:生成使用POST方法的請求對象;
String url = "http://ServerHost:Port/ReplyAjaxGetData.aspx";
HttpPosthttpPost = new HttpPost(url);
第三步:建立請求參數(shù),并將之添加到HTTP請求體的對象;
HttpEntityrequestEntity = new UrlEncodedFormEntity(pairs);
httpPost.setEntity(requestEntity);
第四步:執(zhí)行請求對象,獲取服務(wù)器返回的相應(yīng)對象;
HttpResponse response = httpClient.execute(httpPost);
第五步:檢查相應(yīng)的狀態(tài)是否正常,狀態(tài)碼的值是200表示正常;
if (response.getStatusLine().getStatusCode() == 200) {
第六步:從相應(yīng)對象當中取出數(shù)據(jù),放到entity當中;
HttpEntity entity = response.getEntity();
BufferedReaderreader = new BufferedReader(new InputStreamReader(entity.getContent()));
第七步:解析返回JSON數(shù)據(jù),并判斷返回數(shù)據(jù)。
if(res0.equals("LoginOK"))
{//登錄成功
……}
else {//登錄失敗
……}}
ASPX網(wǎng)頁不用寫界面,只要在頁面的Page_Load事件中處理發(fā)送過來的請求即可。主要過程如下:
第一步:取得HTTP請求的參數(shù);
stringcmdAction = Request["Action"];
第二步:判斷請求參數(shù)的值,可要據(jù)不同值做不同響應(yīng);
switch (cmdAction)
{ case“checklogin”:
//進一步讀取更詳細的請求參數(shù)
param1 = Request.Params["Table"];
param2 = Request.Params["id"];
//查詢數(shù)據(jù)庫……返回結(jié)果
result=……;
break;
case “”:……;break;}
第三步:將結(jié)果輸出到Android端。
Response.Write(result);
Response.End();
這種使用ASPX網(wǎng)頁代理訪問數(shù)據(jù)的方法相較其他方法而言比較簡單,也比較安全,將數(shù)據(jù)庫相關(guān)重要的信息隱藏在了Web服務(wù)器上,安全性由Web服務(wù)器的安全來決定,相比Android直接訪問數(shù)據(jù)要安全得多,在Android也只要提供訪問ASPX網(wǎng)頁的URL及相關(guān)請求參數(shù),如果要對數(shù)據(jù)進行操縱,最好再加上驗證是否是合法用戶之后才能充許更新數(shù)據(jù)。
2.2 使用服務(wù)器端的中間層代理軟件訪問網(wǎng)絡(luò)數(shù)據(jù)庫
服務(wù)器端的中間層代理軟件(Agent Access Database Software,簡稱AADBS),是在某Android項目中開發(fā)的專為代理訪問數(shù)據(jù)庫的程序,它支持代理多個App軟件訪問自己專屬的數(shù)據(jù)庫,將多個不同的App軟件的數(shù)據(jù)放在AADBS的后方。它不僅支持Android訪問遠程網(wǎng)絡(luò)數(shù)據(jù)庫,其他嵌入式系統(tǒng)也可以。
AADBS的主要工作原理是接收移動端程序發(fā)送來的數(shù)據(jù)訪問請求,并找到相應(yīng)數(shù)據(jù)庫進行代理訪問,將訪問結(jié)果返回給移動端程序,大體結(jié)構(gòu)如圖1所示。
具體過程是:1) 由守護線程等待移動端程序發(fā)送過來的數(shù)據(jù)訪問連接,第一次連接的時候移動端程序發(fā)送三個參數(shù),用戶名,密碼,移動程序名,移動程序名經(jīng)查詢轉(zhuǎn)換為要訪問的數(shù)據(jù)庫名(在AADBS服務(wù)器上內(nèi)置有數(shù)據(jù)庫,存儲移動程序名,數(shù)據(jù)庫IP地址,端口號,數(shù)據(jù)庫名,數(shù)據(jù)庫訪問用戶名,數(shù)據(jù)庫訪問密碼等信息)。經(jīng)驗證用戶名與密碼成功后建立SESSION會話對象,進行數(shù)據(jù)訪問。2) 移動程序發(fā)送過來的數(shù)據(jù)流中傳送SQL指令被打包為一個消息放到傳入消息隊列,由消息處理線程從消息隊列中提取消息,傳送至對應(yīng)的數(shù)據(jù)庫執(zhí)行SQL指令。3) 將SQL執(zhí)行結(jié)果打包放到傳出消息隊列。由消息發(fā)送線程通過之前建立的數(shù)據(jù)流將查詢結(jié)果返回給移動程序端。AADBS內(nèi)部結(jié)構(gòu)如圖2所示。
AADBS是用C#程序設(shè)計語言基于.net平臺開發(fā)的,具有很多優(yōu)點:1)采用流行的面向?qū)ο蠹夹g(shù)將各對象進行封裝,使用軟件具有較好的軟件結(jié)構(gòu)及較好的擴展性。2)將各消息處理模塊封裝成線程,大大提升軟件并發(fā)執(zhí)行效率,使代理訪問數(shù)據(jù)庫服務(wù)能同時處理多個連接訪問請求,并且不因某個連接阻塞而影響其他的數(shù)據(jù)訪問連接。3)在服務(wù)器上可支持多種數(shù)據(jù)庫驅(qū)動程序,不受移動端系統(tǒng)環(huán)境的限制,可訪問多種類型的數(shù)據(jù)庫。4)在AADBS中加入日志記錄功能,記錄訪問者IP、執(zhí)行的SQL指令等信息,可以實現(xiàn)數(shù)據(jù)訪問的追溯以及方便數(shù)據(jù)恢復(fù)等。
最后,在移動端程序中編寫類似于C#中的DataTable(數(shù)據(jù)表)類,DataRow(數(shù)據(jù)行)類等的類包,以及從數(shù)據(jù)流中提出數(shù)據(jù)的方法等。
3 結(jié)論
經(jīng)實際使用環(huán)境的檢驗,App上線運行以來,以上兩種方法代理移動程序訪問網(wǎng)絡(luò)數(shù)據(jù)庫的響應(yīng)速度令人滿意。重要的是數(shù)據(jù)庫的安全性得到了很好的解決,將數(shù)據(jù)庫訪問的信息成功地隱藏在了服務(wù)器上,當然這要做好服務(wù)器安全防護。使用服務(wù)器端的中間層代理軟件(AADBS)訪問數(shù)據(jù)庫的方式不僅將數(shù)據(jù)庫隱藏在了服務(wù)器的后方,還支持代理多個App的網(wǎng)絡(luò)數(shù)據(jù)庫訪問功能(只需在AADBS的數(shù)據(jù)庫中增加一行記錄)。
參考文獻:
[1] 彭鳳凌.安卓手機與數(shù)據(jù)庫交互系統(tǒng)的設(shè)計與實現(xiàn)[J].計算機工程與設(shè)計,2013,34(11):3907-3911.
[2] 田佳影.基于HttpClient的Android遠程數(shù)據(jù)庫訪問[J].電子世界.
[3] 龔成瑩,等.基于JSON的Android移動終端與PHP及MySQL數(shù)據(jù)通信[J].工業(yè)儀表與自動化裝置,2013(1):63-65.