【发布时间】:2011-02-22 18:17:08
【问题描述】:
大家。 我正在开发一个 django/mod_wsgi/apache2 网站,该网站使用 https 为所有请求和响应提供敏感信息。如果用户未通过身份验证,所有视图都将被写入重定向。它还有几个视图,旨在像 RESTful Web 服务一样运行。
我现在正在编写一个脚本,它使用 urllib/urllib2 来联系其中的几个服务,以便下载一系列非常大的文件。我在尝试登录时遇到了 403: FORBIDDEN 错误。
我用于身份验证和登录的(草稿)方法是:
def login( base_address, username=None, password=None ):
# prompt for the username (if needed), password
if username == None:
username = raw_input( 'Username: ' )
if password == None:
password = getpass.getpass( 'Password: ' )
log.info( 'Logging in %s' % username )
# fetch the login page in order to get the csrf token
cookieHandler = urllib2.HTTPCookieProcessor()
opener = urllib2.build_opener( urllib2.HTTPSHandler(), cookieHandler )
urllib2.install_opener( opener )
login_url = base_address + PATH_TO_LOGIN
log.debug( "login_url: " + login_url )
login_page = opener.open( login_url )
# attempt to get the csrf token from the cookie jar
csrf_cookie = None
for cookie in cookieHandler.cookiejar:
if cookie.name == 'csrftoken':
csrf_cookie = cookie
break
if not cookie:
raise IOError( "No csrf cookie found" )
log.debug( "found csrf cookie: " + str( csrf_cookie ) )
log.debug( "csrf_token = %s" % csrf_cookie.value )
# login using the usr, pwd, and csrf token
login_data = urllib.urlencode( dict(
username=username, password=password,
csrfmiddlewaretoken=csrf_cookie.value ) )
log.debug( "login_data: %s" % login_data )
req = urllib2.Request( login_url, login_data )
response = urllib2.urlopen( req )
# <--- 403: FORBIDDEN here
log.debug( 'response url:\n' + str( response.geturl() ) + '\n' )
log.debug( 'response info:\n' + str( response.info() ) + '\n' )
# should redirect to the welcome page here, if back at log in - refused
if response.geturl() == login_url:
raise IOError( 'Authentication refused' )
log.info( '\t%s is logged in' % username )
# save the cookies/opener for further actions
return opener
我正在使用 HTTPCookieHandler 在脚本端存储 Django 的身份验证 cookie,以便我可以访问 Web 服务并通过我的重定向。
我知道如果我不将 csrf 令牌与登录信息一起传递,那么用于 Django 的 CSRFmiddleware 将会把我赶出去,所以我首先从第一页/表单加载的 cookiejar 中提取它。就像我提到的,这适用于网站的 http/development 版本。
具体来说,我在尝试通过 https 连接将凭据发布到登录页面/表单时收到 403。此方法在使用 http 连接的开发服务器上使用时有效。
没有阻止访问该区域的 Apache 目录指令(我可以看到)。该脚本在没有发布数据的情况下成功连接到登录页面,所以我认为这会让 Apache 没有问题(但我可能是错的)。
我使用的 python 安装都是用 SSL 编译的。
我还了解到 urllib2 不允许通过代理进行 https 连接。我对代理不是很有经验,所以我不知道使用远程机器上的脚本是否实际上是代理连接,以及这是否会成为问题。这会导致访问问题吗?
据我所知,问题出在 cookie 和发布数据的组合中,但我不清楚从哪里获取它。
任何帮助将不胜感激。谢谢
【问题讨论】:
标签: python django web-services https urllib2