如何检测客户端用于访问Django Web服务的实际URL?

时间:2012-07-06 04:30:08

标签: python django wsgi

我已经实现了一种身份验证方案,模仿亚马逊在我的Django Web服务上使用S3做的事情。每个请求都使用机密签名。要签名的字符串包括所访问资源的URL。

例如,如果客户端发出http://myservices.org/users的GET请求,则客户端必须构建包含string_to_sign的{​​{1}}。当服务器处理请求时,它还将构造一个http://myservices.org/users,并且可以根据从WSGI包装器请求对象获知的信息包含相同的URL。

我的问题是,当客户端决定包含端口号(例如string_to_sign)时,服务器代码会构造一个不正确的http://myservices.org:80/users,因为我不知道如何获取实际的URL客户使用。 WSGI包装器不让我知道URL包含端口号。

有没有办法让Django应用程序学习属于HTTP请求的实际URL?我是否需要设置某种位于WSGI包装器前面的请求处理程序,以便访问原始HTTP请求并自行提取URL?

2 个答案:

答案 0 :(得分:1)

你要求不可能的事。您所拥有的只是请求的第一行,不包括网络位置(主机名和端口号)。您通常会获得一个主机头(HTTP 1.0或更高版本),其中可能包含或不包含端口号。

你可能想看看django-fost-authn,它实现了一个与亚马逊非常类似的方案。

即使您不使用它并且更喜欢自己的,您也应该能够看到如何在预签名计算中完成请求的规范化。最相关的观察是它只使用HTTP请求本身内部的因子。它允许添加自定义标头以包含在已签名的标头集中,您可以坚持认为主机标头已签名。

特别注意如何在fost-authn / signature.py

中生成文档

答案 1 :(得分:1)

虽然它可能并不总是适用于不同的浏览器和HTTP版本,但您可以使用request.META['HTTP_HOST']。对于我的本地开发服务器,现在返回“localhost:8000”,然后我可以通过中间的冒号拆分以分别获得两个部分。

此外,您可能会在HttpRequest类的get_host()方法中找到一些用法。来自the Django documentation

  

使用来自HTTP_X_FORWARDED_HOST(如果已启用USE_X_FORWARDED_HOST)和HTTP_HOST标头的信息按此顺序返回请求的发起主机。如果它们没有提供值,则该方法使用SERVER_NAME和SERVER_PORT的组合,如PEP 3333中所述。

     

示例:“127.0.0.1:8000”