gpt4 book ai didi

django - 以编程方式使用 Cypress.io 登录 Django 服务器(不使用 UI)

转载 作者:行者123 更新时间:2023-12-05 00:13:11 27 4
gpt4 key购买 nike

必须遗漏一些明显的东西,但由于其 CSRF 保护,我非常坚持登录 Django。

我看了Check out our example recipes using cy.getCookie() to test logging in using HTML web forms但如果它建议的第一件事是禁用 CSRF,那真的没有多大帮助。

Django想要什么:

这是一个正常的、受 CSRF 保护的 Django 登录 View 在其传入的 POST 数据中所期望的:

csrfmiddlewaretoken=Y5WscShtwZn3e1eCyahdqPURbfHczLyXfyPRsEOWacdUcGNYUn2EK6pWyicTLSXT
username=guest
password=password
next

它没有在请求 header 中查找 CSRF,也没有设置 x-csrf-token在响应头上。

enter image description here

而且,使用我的代码,我永远不会传入让 Django 返回 403 错误的 csrf token 。
Cypress.Commands.add("login", (username, password) => {
var login_url = Cypress.env("login_url");

cy.visit(login_url)

var hidden_token = cy.get("input[name='csrfmiddlewaretoken']").value;
console.log(`hidden_token:${hidden_token}:`)

console.log(`visited:${login_url}`)
var cookie = cy.getCookie('csrftoken');
// debugger;

var csrftoken = cy.getCookie('csrftoken').value;
console.log(`csrftoken:${csrftoken}:`)
console.log(`request.POST`)

cy.request({
method: 'POST',
form: true,
url: login_url,
// body: {'username': 'guest', 'password': 'password', 'csrfmiddlewaretoken': cy.getCookie('csrftoken').value}
body: {'username': 'guest', 'password': 'password', 'csrfmiddlewaretoken': hidden_token}
})
})

Cypress 的错误:

enter image description here

我怀疑 POST 数据与 undefined 的 token 有关。通过隐藏表单输入或 cookie 获取方法,如 console.log 所示对于任何一个。

现在,我已经开始查看 https://github.com/cypress-io/cypress-example-recipes/tree/master/examples/logging-in__csrf-tokens我想我应该可以调整 策略 #1:从 HTML 解析 token 接机 $("input[name='csrfmiddlewaretoken']").value但我希望以前有人这样做过。

我的另一个想法是有条件地向 Django 添加一个请求中间件,该中间件将从请求 header 中获取 csrftoken 并在丢失时注入(inject) POST 表单数据。如果我将它插入到 CSRF 之前触发,那会起作用吗?

最后,我打算排除 sessionid token 不会被重置,这样我就可以在登录一次后运行多个测试。

env:Django 1.10,cypress 1.4.2,现在升级到 2.0.0,同样的问题。

最佳答案

您可以使用 HEAD 获取登录所需的第一个 CSRF token 请求并查看 cookie(无需解析页面)。
你也可以有你的自定义cy.login()返回 token (异步,所以你需要使用 .then() )而不是调用 cy.getCookie('csrftoken')如果您之后需要一个 token 来进行 POST 请求等,则再次:

Cypress.Commands.add('login', (username, password) => {

return cy.request({
url: '/login/',
method: 'HEAD' // cookies are in the HTTP headers, so HEAD suffices
}).then(() => {

cy.getCookie('sessionid').should('not.exist')
cy.getCookie('csrftoken').its('value').then((token) => {
let oldToken = token
cy.request({
url: '/login/',
method: 'POST',
form: true,
followRedirect: false, // no need to retrieve the page after login
body: {
username: username,
password: password,
csrfmiddlewaretoken: token
}
}).then(() => {

cy.getCookie('sessionid').should('exist')
return cy.getCookie('csrftoken').its('value')

})
})
})

})
注意:登录后 token 会发生变化,因此两个 cy.getCookie('csrftoken')来电。
之后,您可以在测试中按以下方式使用它(请参阅 https://docs.djangoproject.com/en/dev/ref/csrf/ 了解为什么需要 header ):
cy.login().then((csrfToken) => {

cy.request({
method: 'POST',
url: '/api/baz/',
body: { 'foo': 'bar' },
headers: { 'X-CSRFToken': csrfToken }
})

})

关于django - 以编程方式使用 Cypress.io 登录 Django 服务器(不使用 UI),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48835058/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com