Bri*_*ant 6 django cookies selenium csrf django-csrf
我正在尝试使用Django和Selenium创建一个简单的登录测试,但由于CSRF失败而获得403.我期待中间件在GET请求上添加cookie,然后在POST上解析它.
这是我到目前为止检查的内容:
1. Cookie是否在GET请求中设置/accounts/login/
?
是的,cookie正在
process_response
方法中设置
2. Selenium驱动程序上是否提供cookie?
是
ipdb> self.selenium.get_cookies()
[{u'domain': u'localhost', u'name': u'csrftoken', u'value': u'DzNbEn9kZw0WZQ4OsRLouriFN5MOIQos', u'expiry': 1470691410, u'path': u'/', u'httpOnly': False, u'secure': True}]
Run Code Online (Sandbox Code Playgroud)
3.在POST请求期间是否找到了cookie?
不,这个尝试/除了
django.middleware.CsrfViewMiddleware.process_view
失败:
try:
csrf_token = _sanitize_token(
request.COOKIES[settings.CSRF_COOKIE_NAME])
# Use same token next time
request.META['CSRF_COOKIE'] = csrf_token
except KeyError:
csrf_token = None
# Generate token and store it in the request, so it's
# available to the view.
request.META["CSRF_COOKIE"] = _get_new_csrf_key()
Run Code Online (Sandbox Code Playgroud)
码
class TestLogin(StaticLiveServerTestCase):
@classmethod
def setUpClass(cls):
cls.selenium = getattr(webdriver, settings.SELENIUM_WEBDRIVER)()
cls.selenium.maximize_window()
cls.selenium.implicitly_wait(5)
super(TestLogin, cls).setUpClass()
@classmethod
def tearDownClass(cls):
cls.selenium.quit()
super(TestLogin, cls).tearDownClass()
def test_login(self):
self.selenium.get('{}{}'.format(self.live_server_url, '/accounts/login/?next=/'))
assert "Django" in self.selenium.title
un_el = self.selenium.find_element_by_id('id_username').send_keys('the_un')
pw_el = self.selenium.find_element_by_id('id_password')
pw_el.send_keys('the_pw')
pw_el.send_keys(Keys.RETURN)
try:
WebDriverWait(self.selenium, 5).until(EC.title_contains("New Title"))
except TimeoutException as e:
msg = "Could not find 'New Title' in title. Current title: {}".format(self.selenium.title)
raise TimeoutException(msg)
finally:
self.selenium.quit()
Run Code Online (Sandbox Code Playgroud)
题
我可以尝试下一步调试这个?
老问题,但在纠结了几个小时后,答案很简单。
来自文档:
如果浏览器最初通过 HTTP(大多数浏览器的默认设置)进行连接,则现有 cookie 可能会被泄露。因此,您应该将 SESSION_COOKIE_SECURE 和 CSRF_COOKIE_SECURE 设置为 True。这指示浏览器仅通过 HTTPS 连接发送这些 cookie。请注意,这意味着会话将无法通过 HTTP 运行,并且 CSRF 保护将阻止通过 HTTP 接受任何 POST 数据(如果您将所有 HTTP 流量重定向到 HTTPS,这将没问题)。
和我一样,您可能在大部分工作中 使用django_extensions + Werkzeug ,并且默认情况下通过 SSL 运行所有本地工作。
如果您正在使用unittest
它的 Django 版本,我建议您在测试运行时修改这些设置,如下所示:
...
from django.conf import settings
class ProfilePagetest(LiveServerTestCase):
def setUp(self):
settings.CSRF_COOKIE_SECURE = False
settings.SESSION_COOKIE_SECURE = False
self.url = reverse('clientpage:profile')
self.username = 'name@names.com'
self.password = 'strange decisions...'
get_user_model().objects.create_user(self.username, self.username, self.password)
self.browser = webdriver.Firefox()
Run Code Online (Sandbox Code Playgroud)
这应该可以解决 CSRF 验证问题。
归档时间: |
|
查看次数: |
1629 次 |
最近记录: |