GAE:POST 可以作为本地 HTML 文件,但不能用于 GAE SDK 或 GAE 基础设施

GAE: POST OK as a local HTML file but not on GAE SDK or GAE infrastructure

我们有一个网站,允许用户使用隐藏输入登录,以 HTML 形式传递 usernamepassword,如下所示(我知道这是不安全的,但这就是我被要求做 :-( ).

<form method="post" action="https://...">
  <input name="username" value="..." type="hidden">
  <input name="password" value="..." type="hidden">
  <input type="submit" value="submit">
</form>

如果HTML文件保存为本地HTML文件,我提交表单就可以登录成功(浏览器显示的URL是file:///.../xxx.html ).

但是,如果我使用 GAE SDK 呈现 HTML 文件,我将无法登录,网站会抱怨我正在尝试通过未知来源登录(URL在浏览器中显示为 http://localhost:8080/).

如果我将系统部署到 GAE 基础架构,我也无法登录,并出现与上述相同的错误消息(浏览器中显示的 URL 是 http://xxxxx.appspot.com)。

我想知道本地 HTML 表单和网站呈现的表单有什么区别。

如何从网站呈现的表单启用登录?

重要的部分是您的浏览器和您正在使用的日志记录服务之间的最终 HTTP 通信,post 形式将在最后转换为该形式。为了查看任何差异,您可以使用任何浏览器( Google->View->Developer->Developer Tools )并在提交表单时查看网络事件。您会注意到由文件制作的 POST 和由本地或云服务器(如 Google SDK 或 Google App Engine)提供的文件制作的 POST 之间的一些差异,我做了一个快速测试,主要区别是:

当 POSTING 来自文件时:

来源:空

并且当 POSTING 来自 html 来自服务器时:

Origin:http://localhost:26124
Referer:http://localhost:26124/testform/

从服务器端的角度,你可以设置一个模型POST监听器(我在SDK上做的),这是代码:

class TestFormHandler(BaseHandler):
    def get(self):
        form = """
              <form method="post" action="">
              <input name="username" value="valueusernamme" type="hidden">
              <input name="password" value="valuepassword" type="hidden">
              <input type="submit" value="submit">
              </form>
        """
    self.response.out.write(form)

def post(self):
    logging.info(self.request.body)
    logging.info(self.request.headers)
    logging.info(self.request.params)
    logging.info(self.request.cookies)

然后使用带有表单的文件(确保表单操作是本地或云服务本地主机的地址和端口,如果它来自您自己的机器),或访问您设置的服务(GET Handler returns 以前的形式)。

打印 body、headers、参数和 cookie 后的形式:

与文件 POST:

username=valueusernamme&password=valuepassword

{'X-Appengine-Country': 'ZZ', 'Content-Type': 'application/x-www-form-urlencoded', 'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Accept-Language': 'es-419,es;q=0.8,en;q=0.6', 'Content_Length': '46', 'Content-Length': '46', 'Content_Type': 'application/x-www-form-urlencoded', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.69 Safari/537.36', 'Host': 'localhost:26124', 'Origin': 'null', 'Pragma': 'no-cache', 'Cookie': 'dev_appserver_login="test@example.com:True:185804764220139124118"; PHPSESSID=f87c32d417539f8d2903ac76dc5fef1f; language_id=1; __atuvc=0%7C43%2C1%7C44%2C8%7C45%2C0%7C46%2C54%7C47; session=eyJfY3NyZl90b2tlbiI6IjVzcVhEayJ9|1418620181|f01cc7c352763ebe30a0c1d2a34f063112641bbd; _ga=GA1.1.629360734.1406657652; hl=es_ES', 'Cache-Control': 'no-cache'}

UnicodeMultiDict([(u'username', u'valueusernamme'), (u'password', '******')])

UnicodeMultiDict([(u'__atuvc', u'0%7C43%2C1%7C44%2C8%7C45%2C0%7C46%2C54%7C47'), (u'PHPSESSID', u'f87c32d417539f8d2903ac76dc5fef1f'), (u'dev_appserver_login', u'test@example.com:True:185804764220139124118'), (u'session', u'eyJfY3NyZl90b2tlbiI6IjVzcVhEayJ9|1418620181|f01cc7c352763ebe30a0c1d2a34f063112641bbd'), (u'_ga', u'GA1.1.629360734.1406657652'), (u'language_id', u'1'), (u'hl', u'es_ES')])

使用从您的服务器提供的文件:

username=valueusernamme&password=valuepassword

{'X-Appengine-Country': 'ZZ', 'Content-Type': 'application/x-www-form-urlencoded', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Accept-Language': 'es-419,es;q=0.8,en;q=0.6', 'Content_Length': '46', 'Content-Length': '46', 'Referer': 'http://localhost:26124/testform/', 'Content_Type': 'application/x-www-form-urlencoded', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.69 Safari/537.36', 'Host': 'localhost:26124', 'Origin': 'http://localhost:26124', 'Pragma': 'no-cache', 'Cookie': 'dev_appserver_login="test@example.com:True:185804764220139124118"; PHPSESSID=f87c32d417539f8d2903ac76dc5fef1f; language_id=1; __atuvc=0%7C43%2C1%7C44%2C8%7C45%2C0%7C46%2C54%7C47; session=eyJfY3NyZl90b2tlbiI6IjVzcVhEayJ9|1418620181|f01cc7c352763ebe30a0c1d2a34f063112641bbd; _ga=GA1.1.629360734.1406657652; hl=es_ES', 'Cache-Control': 'no-cache'}

UnicodeMultiDict([(u'username', u'valueusernamme'), (u'password', '******')])

UnicodeMultiDict([(u'__atuvc', u'0%7C43%2C1%7C44%2C8%7C45%2C0%7C46%2C54%7C47'), (u'PHPSESSID', u'f87c32d417539f8d2903ac76dc5fef1f'), (u'dev_appserver_login', u'test@example.com:True:185804764220139124118'), (u'session', u'eyJfY3NyZl90b2tlbiI6IjVzcVhEayJ9|1418620181|f01cc7c352763ebe30a0c1d2a34f063112641bbd'), (u'_ga', u'GA1.1.629360734.1406657652'), (u'language_id', u'1'), (u'hl', u'es_ES')])

有些服务会检查请求的来源,并可以使用来源或引用来过滤访问,我会尝试查看日志记录服务,看看他们是否有这方面的东西。