2013-04-13 64 views
0

我正在使用json請求登錄並顯示與用戶有關的消息。但是如果我從瀏覽器發出相同的請求,它仍然有效。我爲我的應用程序使用PHP-MYSQL。 我沒有任何網站,所以我將需要爲應用程序本身的答案。使用json保護http請求(android)

我正在使用Facebook的SDK與Android應用程序,所以我沒有任何密碼。我想確保用戶和用戶數據配置文件之間的聊天消息在被調用時提供。

我的問題是:

  1. 如何確保通話只應用內進行?

  2. 當有人試圖在瀏覽器中複製並粘貼代碼時,我該如何保護通話?

3.10秒後創建的消息有超時,所以相同的url和msg不能被重用。

我有http調用像http:/example.com/login=emailId;

get msgs:http:/example.com/getMsgs/user=uiniqueNo;

我已經提供了上述鏈接,因爲我在應用程序中使用它並且工作正常,但不安全。 請給我建議一些文件和過程。我已經檢查過這個鏈接Protect HTTP request from being called by others,但它不清楚。請給我建議任何具有上述要求的教程。在此先感謝。我真的很感謝幫助。

public class CustomizedListView extends Activity { 
    // All static variables 
    static final String URL = "http://example.com/getmsgs/userno=123"; 
    // XML node keys 
    static final String KEY_SONG = "song"; // parent node 
    static final String KEY_ID = "id"; 
    static final String KEY_TITLE = "title"; 
    static final String KEY_ARTIST = "artist"; 
    static final String KEY_DURATION = "duration"; 
    static final String KEY_THUMB_URL = "thumb_url"; 

    ListView list; 
    LazyAdapter adapter; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 


     ArrayList<HashMap<String, String>> songsList = new ArrayList<HashMap<String, String>>(); 

     JSONObject json = JSONfunctions.getJSONfromURL(URL); 


     try { 
      JSONObject arr2 = json.getJSONObject("feed"); 
      JSONArray arr = arr2.getJSONArray("entry"); 

      for (int i = 0; i < arr.length(); i++) { 
       JSONObject e1 = arr.getJSONObject(i); 

       JSONArray arr3 = e1.getJSONArray("im:image"); 

       JSONObject arr8 = e1.getJSONObject("im:name"); 

       JSONObject arr10 = e1.getJSONObject("im:artist"); 

        JSONObject e12 = arr3.getJSONObject(0); 

      // creating new HashMap 
      HashMap<String, String> map = new HashMap<String, String>(); 

      map.put(KEY_THUMB_URL, e12.getString("label")); 

      map.put(KEY_ARTIST, arr8.getString("label")); 
      map.put(KEY_TITLE, arr10.getString("label")); 
      // adding HashList to ArrayList 
      songsList.add(map); 
      } 

     } catch (JSONException e) { 
      // Log.e("log_tag", "Error parsing data "+e.toString()); 
      Toast.makeText(getBaseContext(), 
        "Network communication error!", 5).show(); 
     } 


     list=(ListView)findViewById(R.id.list); 

     // Getting adapter by passing xml data ArrayList 
     adapter=new LazyAdapter(this, songsList);   
     list.setAdapter(adapter); 

     // Click event for single list row 
     list.setOnItemClickListener(new OnItemClickListener() { 

      @SuppressWarnings("unchecked") 
      @Override 
      public void onItemClick(AdapterView<?> parent, View view, 
        int position, long id) { 


       HashMap<String, String> o = (HashMap<String, String>) list.getItemAtPosition(position); 
       Toast.makeText(CustomizedListView.this, "ID '" + o.get("KEY_TITLE") + "' was clicked.", Toast.LENGTH_SHORT).show(); 

      } 
     });  
    } 
} 

在上面的代碼中任何人都可以猜到usersno但我怎麼保證,在應用程序和PHP服務器。所以,即使嗅探程序中沒有123被使用,並進行反向工程從apk文件獲取代碼該數據仍然是保護和加密應該在OS深哪些用戶不能打破,因此我可以在服務器PHP解密代碼,用戶將沒有辦法隨意輸入任何內容爲123

<?php 

$strno=$_GET['strno']; 

if (isset($strno)) 
{ 
     $connect=mysql_connect("localhost","test","test") or die ('Connection error!!!'); 
     mysql_select_db("test") or die ('Database error!!!'); 

    $query=mysql_query("select sno FROM users  where strno='$strno';"); 
    while($row = mysql_fetch_assoc($query)) 

    { 
     $jsonoutput='{"json":{ 
      "msg_sub":"'.$row['msg_sub'].'", 
      }}'; 
    } 

} 

echo trim($jsonoutput); 
mysql_close($connect) or die ('Unable to close connection-error!!!'); 
} 

?> 
+0

我注意到你有'http:// example.com/getmsgs/limit = 20/userno = 123'作爲你的api端點。你可以發佈在那裏運行的代碼嗎? – 1337holiday

+0

我在上面,現在隨時都在。 –

+0

也增加了php代碼。其簡化。 –

回答

0

有兩種選擇爲了達成這個。首先是使用GET方法,你可以在你正在尋找的服務器端創建一個特定的參數。例如,從您的Android應用發送http://www.my-backend.com/api/test_api?my_secure_code=thisIsTestString和服務器返回正確的響應,但如果您發送http://www.my-backend.com/api/test_api?my_secure_code=thatsAnotherString,則您在請求中搜索的參數值不是thisIsTestString,因此您應該返回錯誤消息。

在我看來,第二種方法實現這一點比較好,因爲使用GET在我看來並不是那麼簡單。它比使用POST更容易。在這種情況下,您必須發送my_secure_param作爲post參數,您可以通過在瀏覽器中輸入來使用該參數(通過安裝插件發送請求,仍然可以通過瀏覽器實現此目的)。所以我認爲這裏最好的解決方案是使用POST請求,而連接後端使用MD5SHA1發送一些散列字符串(至少這是我們與我們的服務器保護連接的方式+額外的額外功能)。

編輯:關於評論,你可以做到這一點的方式是通過爲你的服務器上的特定用戶創建某種標識,而不信任Facebook。這只是一個建議......例如,您可以從Facebook獲取id用戶並創建一個獨特的哈希ID,您將存儲在您的服務器中,並且每次從應用發送請求時,都必須發送該唯一ID,該id將在應用中創建用於在服務器上創建它的方式。如果這個匹配,每次有人發送消息,你將不得不檢查那個散列,如果不是隻是返回錯誤..並且不要忘記,請使用POST請求而不是GET!沒有辦法在不改變服務器後端代碼的情況下實現這樣的功能。

+0

謝謝你的迴應Sir.But我需要它關於應用程序本身,因爲我沒有一個網站相同.PLease你可以提供我的鏈接,這將給出一個樣本/例子來回你的建議。我會很感激幫助。再次感謝先生。 –

+0

我更新了這個問題,因爲我正在使用Facebook sdk登錄我的應用程序。 –

+0

您是否使用其他服務器向用戶發送消息? – hardartcore

1

好了沒有方式實際上完全保護這個系統,除非你使用https你的API和JS客戶端之間傳輸數據。

這是你做什麼:

  1. 首先在你的數據庫端
  2. 接下來,創建一個用戶登錄系統,用戶名/密碼錶創建一個表單供用戶登錄
  3. 只要用戶嘗試要訪問api,你的服務器將檢查它是否爲該用戶設置了一個會話,他們將不得不登錄或通過一個現有的會話ID,這將授予他們訪問權
  4. 接下來購買一個https證書,以確保您的數據被安全地傳送
  5. 現在對每個請求的API,服務器總是檢查,如果他們的用戶發送了有效的會話ID,如果沒有,便索性將其重定向到登錄頁面

這幾乎是唯一的出路您可以爲您的系統添加安全性。最重要的部分是https證書。如果沒有這個,用戶/密碼有多好並不重要,它仍然可能會受到影響。

編輯

下面是一些示例代碼,讓你開始。這段代碼沒有經過測試,只是在那裏給你一個想法。你可以閱讀所有關於會議here

<?php 

    /* 
     like I said earlier, you need to have a "login" screen on your app 
     - when the user clicks login it POSTS the request back here 
    */ 

    if(isset($_SESSION['username'])){ 
     //the username is in the session so it means 
     //theyre already logged in 
     //not sure what strno is doing but you can do that here 

     $strno=$_GET['strno']; 

     if (isset($strno)) 
     { 
       $connect=mysql_connect("localhost","test","test") or die ('Connection error!!!'); 
       mysql_select_db("test") or die ('Database error!!!'); 

      $query=mysql_query("select sno FROM users where strno='$strno';"); 
      while($row = mysql_fetch_assoc($query)) 

      { 
       $jsonoutput='{"json":{ 
        "msg_sub":"'.$row['msg_sub'].'", 
        }}'; 
      } 

     } 

     echo trim($jsonoutput); 
     mysql_close($connect) or die ('Unable to close connection-error!!!'); 

    }else if(isset($_POST) && isset($_POST['username']) && isset($_POST['password'])){ 
     //log them in 
     //query ur database to see if the user exists 
     //if you get a row back then store that row in the session like 
     //note: this is just example code 

     if(/*user is in database, get the row....*/){ 
      session_start(); 
      $_SESSION['username'] = $row['username']; 
     } 
    }else{ 
     die("Access Denied"); 
    } 

?> 
+0

謝謝你的迴應Sir.But我需要它關於應用程序本身,因爲我沒有相同的網站。我還沒有使用會話ID。我也沒有得到創建一個用戶登錄聲明PLease可以你給我提供了一個鏈接,這個鏈接會給你一個解釋你的樣本/例子。我真的很感激這個幫助。再次感謝先生。 –

+0

我更新了這個問題,因爲我正在使用Facebook sdk登錄我的應用程序。 –

+0

好吧,讓它變得非常簡單,如果你試圖訪問'http:/ example.com/getMsgs/user = uiniqueNo',但你沒有權限訪問API,你應該不知道'uniqueNo'是什麼。因此,如果您在不知道「uniqueNo」是什麼的情況下發出請求,它應該重定向到登錄頁面。登錄後,會調用session_start(),它將爲該用戶創建一個唯一的session_id。用戶下一次嘗試訪問API時,他們需要在請求上傳遞他們的session_id。服務器將執行'session_start()'來恢復會話,從而授予對應用程序的訪問權限。 – 1337holiday