通常测试中,需要登录之后才可以进行后续操作,这就需要鉴权。
用户鉴权一般有以下两种:
①基于表单的认证(Cookie&Session)
②基于JWT(Json Web Token)的认证
本章主要记录下基于JWT的认证过程:
①当用户登录成功后,后端服务器生成JWT,并将此JWT返回给客户端
②客户端将此JWT保存在localstorage/sessionstorage中,并在后续每一次请求中将此JWT放在HTTP请求头的authorization中一起发送
③后端服务器收到客户端请求后,对此JWT进行校验
cy.request() 发请求访问接口,通常自定义一个登陆指令,在support/commands.js 下定义一个命令'login_request'用于发登录请求
以下为我实际项目,登录流程较复杂,但流程是一致的,拿到登录接口返回的token,保存在localstorage中,后续visit的时候就可以直接使用。
Cypress.Commands.add('login_request',(uesrname="137000***",password="12**") =>{
cy.request({
url: "/auth/pwdLogin",
method: 'POST',
headers: {
"content-type": 'application/json; charset=UTF-8',
"user-agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36",
"X-Requested-With": "XMLHttpRequest"
},
body: {
"username":"137000**",
"password":"7c4a8d09ca3762af61e59520943dc26494f8941b"
}
})
.its('body')
.as('resp_login')
.then(function () {
expect(this.resp_login.code).to.eq(0)
expect(this.resp_login.msg).to.contain("ok")
//存入localStorage
window.localStorage.setItem('jwt',"Bearer " + this.resp_login.data.access.token) //(自定义名称,值)
})
cy.window().then((window) => { //需在cy.window()才可使用保存在localstorage中的jwt
cy.request({
url: "/auth/anonymousLogin",
method: 'POST',
headers: {
"content-type": 'application/json; charset=UTF-8',
"user-agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36",
"X-Requested-With": "XMLHttpRequest",
"authorization": window.localStorage.getItem('jwt') //获取保存的jwt的值
},
body: {
"companyId": "359"
}
})
.its('body')
.as('resp')
.then(function () {
window.localStorage.setItem('token', "Bearer " + this.resp.data.access.token)
expect(this.resp.msg).to.contain('ok')
})
})
cy.window().then((window) => {
cy.request({
url: "/auth/getSingleLoginMenus",
method: 'POST',
headers: {
"content-type": 'application/json; charset=UTF-8',
"user-agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36",
"authorization": window.localStorage.getItem('token')
}
})
.its('body')
.as('secret')
.then(function () {
expect(this.secret.msg).to.contain("ok")
const url = this.secret.data.list[0].url
const urllist = url.split('code=')
const code = urllist[1]
const de_code = decodeURIComponent(code) //url编码解码
window.localStorage.setItem('secretid', de_code)
})
})
cy.window().then((window) => {
cy.request({
url: "/auth/login",
method: 'POST',
headers: {
"content-type": 'application/json; charset=UTF-8',
"user-agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36",
"authorization": window.localStorage.getItem('token')
},
body: {
"secret": window.localStorage.getItem('secretid')
}
})
.its('body')
.as('loginresp')
.then(function() {
expect(this.loginresp.msg).to.contain("ok")
const authorized = this.loginresp.data.access.token
window.localStorage.setItem('access-token-authorized',authorized) //最后的登录接口返回的token,需保存在特定的access-token-authorized中
})
})
})
如何查看access-token-authorized命名:

image.png
登录后的visit
describe('访问工作台',function () {
before(function () {
cy.login_request() //command.js中定义的登录命令
})
it('访问工作台',function () {
cy.visit('/#/workbench')
cy.url().should('include','workbench')
})
})

image.png