2013-04-13 35 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