如果在股票浏览器上受密码保护的网站后面,APK 下载失败
Posted
技术标签:
【中文标题】如果在股票浏览器上受密码保护的网站后面,APK 下载失败【英文标题】:APK download failure if behind password protected site on stock browser 【发布时间】:2013-07-10 05:06:48 【问题描述】:我在使用 Rails 的服务器上提供 APK 时遇到问题。如果下载链接放在 /public 中,我可以提供 APK。但是,我想用密码保护它。如果我将文件移动到需要 HTTP 身份验证的 URL 后面,那么它会立即在带有 Download Unsuccessful
的股票浏览器上失败。
如果我安装并运行 firefox,firefox 能够下载 APK 并正确安装。
有人知道如何使用 android 的股票浏览器来实现这一点吗?
我已将MIME Type
添加到服务器:
Mime::Type.register "application/vnd.android.package-archive", :apk
我正在尝试在 HTTP 身份验证后发送文件:
send_file "android.apk", :type => 'application/vnd.android.package-archive'
来自 /public 的成功 HTTP 标头:
~ curl -s -D- android.apk -o/dev/null
HTTP/1.1 200 OK
Server: nginx/1.4.1
Date: Thu, 11 Jul 2013 20:06:43 GMT
Content-Type: application/octet-stream
Content-Length: 38673086
Last-Modified: Thu, 11 Jul 2013 20:05:12 GMT
Connection: keep-alive
ETag: "51df0ff8-24e1abe"
Accept-Ranges: bytes
HTTP 身份验证后面的 HTTP 标头不成功:
~ curl -s -D- private/android.apk -o/dev/null
HTTP/1.1 200 OK
Server: nginx/1.4.1
Date: Thu, 11 Jul 2013 20:11:53 GMT
Content-Type: application/octet-stream
Transfer-Encoding: chunked
Connection: keep-alive
Status: 200 OK
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-UA-Compatible: chrome=1
Content-Disposition: attachment; filename="SironaVideoSurvey.apk"
Content-Transfer-Encoding: binary
Cache-Control: private
Set-Cookie: request_method=GET; path=/
X-Request-Id: 6b99f5e5-87f8-4f8c-816c-0034265b3991
X-Runtime: 0.016140
【问题讨论】:
“立即”是指不提示您进行身份验证吗?或者您提供了您的凭据,然后它失败了? 抱歉 - 将更新问题以反映这一点。首先提示我进行身份验证,然后开始下载。下载开始后立即失败。该文件在下载历史记录中被简单命名为“curl
或其他东西来转储成功请求的HTTP 标头吗?我怀疑这些标题可能会给我们一些线索。例如,如果标头包含Content-Disposition: Attachment
,您可能需要对所服务的内容进行一些调整:***.com/questions/4674737/…
转储为编辑。看起来 /public 的成功在内容标题中要简单得多。我尝试使用您链接的建议但没有成功。我会尝试模仿 /public 正在服务的内容标题
一位同事可以在他的 Android 设备上使用最新版本的 Chrome 测试版 (28.0.1500.64) 下载此文件。 Chrome 27 版虽然没有。带有 Android 4.2.2 的股票浏览器也出现故障
【参考方案1】:
提供登录页面,而不是使用 HTTP 身份验证。
使用 php 和 Apache2,您可以执行以下操作:
.htaccess
Options -Indexes
RewriteEngine on
RewriteCond %HTTP_COOKIE PHPSESSID=(\w+)
RewriteCond /tmp/access-%1 -f
RewriteRule ^(.*)$ $1 [L]
RewriteCond %REQUEST_URI !=/login.php
RewriteRule ^(.*)$ /login.php?req=$1 [L]
你也可以把它放在Apache2的sites-enabled
文件夹下的*.conf
文件中。如果您想使用.htaccess
文件,请确保在Apache2 配置中启用AllowOverride All
,否则Apache2 将忽略.htaccess
文件。
login.php
<?php
$password = "supersecret"; //change this
?>
<!DOCTYPE html>
<html>
<head>
<title>Site Login</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
.incorrect
color: red;
</style>
</head>
<body>
<?php
if (isset($_POST["password"]) && ($_POST["password"] == "$password"))
session_start();
touch("/tmp/access-" . session_id());
header("Location: /" . $_GET['req']);
else
if (isset($_POST['password']) || $password == "")
?>
<p class="incorrect">
<b>Incorrect Password</b>
<br>Please enter the correct password
</p>
<?php
else
?>
<p>Please enter the password</p>
<?php
?>
<form method="post">
<p>
<input name="password" type="password" size="25" maxlength="10">
<input value="Login" type="submit">
</p>
</form>
<?php
?>
</body>
</html>
策略是将每个请求重定向到登录页面,来自经过身份验证的会话的请求除外。这包括对下载、图像、CSS 文件、JS 文件等的请求。
身份验证状态通过使用文件名中带有会话 ID 的临时文件从 PHP 与 Apache2 进行通信(它没有任何数据,但它的存在表示一个经过身份验证的会话)。输入正确的密码后,PHP 将创建该文件。然后,如果 Apache2 可以根据请求 cookie 中的会话 ID 检测到文件存在,那么任何后续请求都会正常提供服务。
资产/.htaccess
这有助于将图像和 CSS 等某些资源排除在要求身份验证之外,以便在登录页面上使用它们。假设它们位于assets
文件夹中。只需使用以下内容创建assets/.htaccess
。
Options -Indexes
RewriteEngine off
注意事项
您可以针对其他脚本语言(如 JSP 或 Ruby on Rails)或 Web 服务器(如 Nginx)调整策略。请注意,Options -Indexes
是可选的,但建议使用它,因为它会阻止目录列表。
默认情况下,会话在 24 分钟不活动后过期。这是由php.ini
中的session.gc_maxlifetime
定义的。可以通过使用 PHP 删除会话的临时文件来添加注销功能。
这个例子是一个简单的登录页面,只有一个密码。借助 PHP 的强大功能,您可以将其扩展为您能想象到的任何身份验证管理庞然大物。无论是具有用户名的多个用户、用户配置文件的数据库存储、有限的访问控制、基于 Web 的用户管理等等。
是的,这适用于在旧的 Android 库存浏览器上进行的下载,名为“浏览器”,但 HTTP 身份验证失败。
【讨论】:
【参考方案2】:这看起来是 Android 中的一个(~6 岁!!)错误: https://code.google.com/p/android/issues/detail?id=1353
显然,我们能做的就是给问题加注星标。您可以自己找到互联网上发布的其他 hacky 变通办法,但我不建议将它们中的大多数作为通用解决方案。
也许尝试将文件扩展名更改为全部大写,如下所示: http://www.digiblog.de/2011/04/android-and-the-download-file-headers/
所以这条线变成了:
Content-Disposition: attachment; filename="SironaVideoSurvey.APK"
如果这不起作用,我只建议您告诉您的客户使用其他非库存(和非 Chrome!)浏览器。 :/ 祝你好运。
【讨论】:
感谢您挖掘确切的问题!我最终尝试将扩展名重命名为全部大写,但不幸的是这并没有奏效。我们在公共目录中提供 APK,并尽最大努力隐藏 URL。 APK 不包含任何私人或敏感数据,所以这次我们很幸运!以上是关于如果在股票浏览器上受密码保护的网站后面,APK 下载失败的主要内容,如果未能解决你的问题,请参考以下文章