确定是否从Android应用程序发出HTTP请求?然后适当地回应

时间:2011-06-03 06:23:11

标签: java php android http

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

截至目前,如果您从笔记本电脑或PC上的浏览器ping该URL,服务器将响应并更新服务器上数据库中所需的任何内容。

我想要做的是当在服务器上收到HTTP请求时,我想确定该请求是来自Android设备的Android应用程序,然后使用数据进行响应。我想改变服务器上PHP中的代码,如果HTTP请求来自浏览器或除了我的Android应用程序以外的任何其他内容,它们将显示或重定向到某个页面。

来自应用的典型HTTP请求类似于http://example.com/abc.php?usera=abc&datab=xyz

如果它来自除Android应用程序之外的任何其他地方,我不想以相同的方式回复此URL。这可能吗?什么是实现这一目标的好方法..

感谢您的帮助。

4 个答案:

答案 0 :(得分:9)

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

只需查询并在末尾添加一个密码,然后制作一个可以作为标题发送的MD5(或用作用户代理)。并在服务器上执行相同操作并检查校验和是否相同。

为了让它更安全一点,您可以制作一个时间戳,以便请求仅在短时间内有效。

使您的查询看起来像http://example.com/abc.php?usera=abc&datab=xyz&timestamp=123456789,其中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
}

记住时间戳有点松弛,因为你的服务器时钟和电话时钟可能会有点不同步。

答案 1 :(得分:3)

执行此操作的典型方法是在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

在服务器端,您可以在user-Agent标头上使用正则表达式匹配来确定请求是否源自您的Android应用,并发送相应的响应。

答案 2 :(得分:1)

在Android中创建HttpClient时,可以设置以下内容

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

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

答案 3 :(得分:1)

如果实际请求相同(例如,您无法添加POST或GET变量来主动识别您的请求),则您必须依赖其他内容,例如user-agent。

虽然你可以在你的应用程序中根据你的意愿设置它们(也可以参见@mark_bakker和@mark_allison的答案),你应该知道有办法弄乱这个,所以不要用它来做你的东西真的不希望其他用户看到。

  • Android用户理论上可以更改离开您的应用的请求和离开他/她的网络的请求之间的user_agent字符串。所以不要将它用于“Android用户没有付费,所以不应该看到这个/那个信息”应用程序
  • 反过来说,非Android用户可以更明显地改变他们的用户代理,所以如果你的内容只有付费的Android用户应该看到,他们可能会伪造字符串。

最后,如果你可以改变你的请求可能会更好:你想要一个不同的回复,你应该做一个不同的请求是我的意见。