Cypress登录场景下仅登录后生成CSRF Token的解决方案问询
解决方案
1. 封装公共登录逻辑,避免重复代码
不用在每个spec文件中重复编写登录步骤,你可以把「登录+获取CSRF token」的逻辑封装成Cypress全局自定义命令,所有测试文件都可以直接调用。
首先在cypress/support/commands.js中添加如下代码:
import {Login} from "../../pages/login/Login"; // 封装带CSRF token获取的登录命令 Cypress.Commands.add('loginAndGetCsrf', (email, password) => { cy.visit(Cypress.env('url')) const login = new Login() login.loginCredentials(email, password) // 等待CSRF cookie生成,直接返回token值 return cy.getCookie('YII_CSRF_TOKEN').should('exist').its('value') })
之后在任意需要使用CSRF token的spec文件中,只需一行调用即可:
describe('测试用例集', () => { it('需要携带CSRF token的请求测试', () => { cy.loginAndGetCsrf(Cypress.env('userEmail'), Cypress.env('userPass')).then(csrfToken => { // 后续需要CSRF的请求直接使用该token即可 cy.request({ method: 'POST', url: '/目标接口路径', headers: { 'X-CSRF-Token': csrfToken }, body: { // 你的请求参数 } }) }) }) })
2. 用cy.session缓存登录状态,降低重复登录耗时
如果多个用例都需要登录状态,可以用Cypress的session功能缓存登录后的cookie、localStorage等信息,不用每个用例都重新走一遍UI登录流程,大幅提升测试速度。
修改自定义命令加入session缓存逻辑:
import {Login} from "../../pages/login/Login"; Cypress.Commands.add('loginAndGetCsrf', (email, password) => { return cy.session([email, password], () => { cy.visit(Cypress.env('url')) const login = new Login() login.loginCredentials(email, password) // 验证登录成功,确保CSRF cookie已生成 cy.getCookie('YII_CSRF_TOKEN').should('exist') }).then(() => { return cy.getCookie('YII_CSRF_TOKEN').its('value') }) })
相同账号密码调用该命令时,只会在第一次调用时走实际登录流程,后续调用都会直接复用缓存的登录状态,可直接获取到CSRF token。
3. 用接口登录替代UI登录(可选,性能更高)
如果你们有可直接调用的登录接口,可以跳过UI登录步骤,直接用cy.request走接口完成登录,速度比UI登录快数倍:
Cypress.Commands.add('loginByApiAndGetCsrf', (email, password) => { return cy.session([email, password], () => { cy.request('POST', '/登录接口地址', { email: email, password: password }).its('status').should('eq', 200) cy.getCookie('YII_CSRF_TOKEN').should('exist') }).then(() => { return cy.getCookie('YII_CSRF_TOKEN').its('value') }) })
额外提醒:Yii框架的CSRF token默认会对值做urlencode处理,如果你是放到请求头中提交,记得先做urldecode处理再传入,避免出现校验失败的问题。
内容的提问来源于stack exchange,提问作者cypher_null
相关产品推荐
相关产品推荐

