3

我在使用 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
4

2 回答 2

5

这看起来是 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!)浏览器。:/ 祝你好运。

于 2013-07-22T15:53:38.640 回答
0

提供登录页面而不是使用 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*.conf文件夹中的文件中。sites-enabled如果要使用.htaccess文件,请确保AllowOverride All在 Apache2 配置中启用,否则 Apache2 将忽略.htaccess文件。

登录.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 检测到文件存在,那么任何后续请求都将由 Apache2正常处理。

资产/.htaccess

这有助于将图像和 CSS 等一些资源排除在要求身份验证之外,以便可以在登录页面上使用它们。假设它们在一个assets文件夹中。只需assets/.htaccess使用以下内容创建。

Options -Indexes
RewriteEngine off

笔记

  1. 您可以为其他脚本语言(如 JSP 或 Ruby on Rails)或 Web 服务器(如 Nginx)调整策略。请注意,这Options -Indexes是可选的,但建议使用,因为它会阻止目录列表。

  2. 默认情况下,会话在 24 分钟不活动后过期。这是由session.gc_maxlifetimein定义的php.ini。可以通过使用 PHP 删除会话的临时文件来添加注销功能。

  3. 这个例子是一个简单的登录页面,只有一个密码。借助 PHP 的强大功能,您可以将其扩展为您能想象到的任何身份验证管理庞然大物。无论是具有用户名的多个用户、用于用户配置文件的数据库存储、有限的访问控制、基于 Web 的用户管理等等。

  4. 是的,这适用于在旧版 Android 浏览器上进行的下载,名为“浏览器”,其中 HTTP 身份验证失败。

于 2018-03-09T07:24:59.710 回答