识别是否来自Android应用程序的HTTP请求?然后进行适当的响应


Identify whether HTTP requests from Android App or not? and then respond appropriately

我的Android应用程序有一个与之相关的应用程序小工具,在Android设备上每10分钟更新一次。这些更新向服务器发送HTTP数据请求,解析服务器响应并根据需要更新应用程序。

到目前为止,如果你从笔记本电脑或PC上的浏览器ping到该URL,服务器将做出响应并更新服务器上数据库中所需的内容。

我想做的是,当服务器收到HTTP请求时,我想确定请求是否来自安卓设备的安卓应用程序,然后用数据进行响应。我想更改服务器上PHPs中的代码,如果HTTP请求来自浏览器或除我的Android应用程序之外的任何其他应用程序,它们将显示或重定向到某个页面。

来自应用程序的典型HTTP请求如下http://example.com/abc.php?usera=abc&datab=xyz

如果这个URL来自除安卓应用程序之外的任何其他地方,我不想以同样的方式响应。这可能吗?实现这一目标的好方法是什么。。

谢谢你的帮助。

您可以向请求添加签名,然后在服务器端进行检查。

只需接受查询并在末尾添加一个秘密单词,然后对其进行MD5,即可将其作为标头发送(或用作用户代理)。在服务器上,你也可以这样做,并检查校验和是否相同。

为了更安全,您可以制作一个时间戳,这样请求只在短时间内有效。

使您的查询看起来像http://example.com/abc.php?usera=abc&datab=xyz&timestamp=12346789,其中timestamp是当前时间(在unix时间戳中),并将其添加到您的应用程序中:

public static String makeCheck(String url)
{
    URL u=new URL(url);
    MessageDigest md = MessageDigest.getInstance("MD5");
    u.getQuery();
    md.update(u.getQuery().getBytes());
    BigInteger bn = new BigInteger(1,md.digest("A_SECRET_WORD".getBytes()));
    return bn.toString(16);
}

当你需要添加标题时,可以使用类似的东西:

request.addHeader("X-CHECKSUM", makeCheck(url) );

然后在您的服务器上,您可以使用:

if (md5($_SERVER['QUERY_STRING']."A_SECRET_WORD")!=$_SERVER['X-CHECKSUM']) {
    // Wrong checksum
}
$timediff=60;
if ( $_GET['timestamp']>(time()+$timediff) || $_GET['timestamp']<(time()-$timediff) ) {
    // Bad timestamp
}

记住时间戳要宽松一点,因为你的服务器时钟和手机时钟可能会有点不同步。

执行此操作的典型方法是在HTTP请求中使用User-Agent标头。如果请求来自标准浏览器,它将唯一标识硬件和软件。例如,运行Froyo的Nexus One将具有以下用户代理:

Mozilla/5.0 (Linux; U; Android 2.2; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1

但是,如果您使用HttpClient从应用程序发出请求,您可以自定义HttpClient使用的User-Agent标头,如以下答案所示:Android HTTP User-Agent。

在服务器端,您可以在用户Agent标头上使用regex匹配来确定请求是否来自您的Android应用程序,并发送适当的响应。

如果实际请求是相同的(例如,您无法添加POST或GET变量来主动识别您的请求),则必须依赖其他东西,如用户代理。

虽然你可以在应用程序中根据自己的意愿设置它们(也可以参见@mark_bakker nd@mark_allison的答案),但你应该意识到有很多方法可以解决这个问题,所以不要把它用于你真的不想让其他用户看到的东西。

  • 理论上,安卓用户可以在离开应用程序的请求和离开他/她的网络的请求之间更改user_agent字符串。所以不要将其用于"Android用户没有付款,所以不应该看到这个/那个信息"应用程序
  • 另一方面,非安卓用户显然可以更改他们的用户代理,所以如果你有只有付费安卓用户才能看到的内容,他们可能会伪造字符串

最后,如果可以的话,最好改变你的请求:我认为,如果你想要不同的回复,你应该做不同的请求。

当你在android中创建HttpClient时,你可以设置以下

 client.getParams().setParameter(CoreProtocolPNames.USER_AGENT, "MY Android device identifier");

这将为发送到服务器的每个http请求设置USER_AGENT。在您的服务器上,您可以检索USER_AGENT以确定请求来自您的android设备

相关文章: