使用 json (android) 保护 http 请求
Posted
技术标签:
【中文标题】使用 json (android) 保护 http 请求【英文标题】:protect http request using json (android) 【发布时间】:2013-04-06 04:31:45 【问题描述】:我正在使用 json 请求登录并显示与用户有关的消息。但如果我从浏览器发出相同的请求,它仍然可以工作。我正在为我的 App 使用 php-mysql。 我没有任何网站,所以我需要应用程序本身的答案。
我正在使用带有 android 应用程序的 facebook sdk,所以我没有任何密码。我想在调用时保护用户和用户数据配置文件之间的聊天消息。就是这样。
我的问题是:
如何确保仅在应用内拨打电话?
当某些人试图在浏览器中复制和粘贴代码时,我如何确保通话安全?
3.10秒后创建的消息有超时。所以不能重复使用相同的url和msg。
我有 http://example.com/login=emailId 之类的 http 调用;
获取消息: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 文件中获取代码,数据仍然是保护和加密应该深入操作系统,用户无法破解,因此我可以解密服务器 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!!!');
?>
【问题讨论】:
我注意到你有http://example.com/getmsgs/limit=20/userno=123
作为你的 api 端点。你能发布在那里运行的代码吗?
我在上面。现在随时发布。
也添加了 php 代码。它的简化。
【参考方案1】:
好吧,没有方式可以真正完美地保护这个系统,除非你使用 https 在你的 api 和你的 js 客户端之间传输数据。
这就是你要做的:
-
首先在你的数据库端创建一个用户登录系统,用户名/密码表
接下来创建一个表单供用户登录
每当用户尝试访问 api 时,您的服务器将检查它是否为该用户设置了会话,他们要么必须登录,要么传递现有的会话 ID,这将授予他们访问权限
接下来是购买 https 证书,以确保您的数据安全传输
现在在对 api 的每个请求中,服务器总是检查他们的用户是否发送了有效的 SESSION 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");
?>
【讨论】:
感谢您的回复先生。但我需要它关于应用程序本身,因为我没有相同的网站。另外我没有使用会话 ID。我也没有为用户登录声明请您提供链接,该链接将为您建议的解释提供示例/示例。我非常感谢您的帮助。再次感谢先生。 我也更新了问题,因为我正在使用 facebook sdk 登录我的应用程序。 好吧,让事情变得非常简单,如果您尝试访问http:/example.com/getMsgs/user=uiniqueNo
但您无权访问 api,您不应该知道 uniqueNo
是什么。因此,如果您在不知道uniqueNo
是什么的情况下发出请求,它应该重定向您的登录页面。登录后,session_start()
被调用,这将为该用户创建一个唯一的 session_id。下次用户尝试访问 api 时,他们需要在请求中传递他们的 session_id。服务器将执行session_start()
以恢复会话,从而授予对应用程序的访问权限。
您好,先生,我正在使用 android 应用程序是否可以解决会话 id 部分的问题,因为它适用于应用程序,上面的描述适用于 html。请您在 android 调用中提出类似的建议。
编辑你的问题以包含更多的android代码,如果我能看到你的代码,我可能会更好地帮助你。【参考方案2】:
有两种方法可以实现这一目标。首先是使用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 请求的插件来实现此目的)。所以我认为这里最好的解决方案是使用POST
请求,同时连接到后端使用MD5
或SHA1
发送一些散列字符串(至少这是我们保护与服务器连接的方式+一些额外的东西) .
编辑:关于 cmets,您可以通过在您的服务器上为特定用户创建某种标识来实现此目的,而不是信任 facebook。这只是一个建议...例如,您可以从 facebook 获取 id 用户并创建一个唯一的哈希 id,您将其存储在您的服务器中,并且每次您从应用程序发送请求时,您都必须发送该唯一 id,这将在应用程序中创建的方式与在服务器上创建它的方式相同。如果匹配,则每次有人发送消息时,您都必须检查该哈希值,如果不只是返回错误..别忘了,使用POST
请求而不是GET
!如果不更改服务器后端中的一些代码,就无法实现这样的目标。
【讨论】:
感谢您的回复先生。但我需要它关于应用程序本身,因为我没有相同的网站。请您提供链接以提供示例/示例来解释您建议。我非常感谢您的帮助。再次感谢先生。 我也更新了问题,因为我正在使用 facebook sdk 登录我的应用程序。 您是否使用其他服务器向用户传递消息? 是的,服务器存储与应用程序而不是 Facebook 相关的个人消息,所以我如何确保从浏览器发送和查看其他用户的消息,因为唯一的用户 ID 可能会通过反复试验猜到。跨度> 为了保护来自嗅探器的连接,您可以使用网络证书,并且您应该在您的 android 应用程序中处理信任方法。关于android端的逆向工程,使用proguard混淆你的代码,它是在android中构建的,所以你不会有问题。以上是关于使用 json (android) 保护 http 请求的主要内容,如果未能解决你的问题,请参考以下文章
如何保护与 Android 应用程序交互的 PHP JSON api 端点?
如何在 Android 中打印受 Auth0-JWT 保护的私有 API 端点 JSON 对象?
如何在 .NET WCF 中保护 HTTP JSON Web 服务