axios:在没有浏览器的情况下进行测试时,如何在成功授权后保留会话并随后续请求发送



在这个测试用例中,我向使用passportjs local运行的ExpressJS服务器发送了一个带有userId和密码的axios post请求。服务器以状态代码200进行响应,并发送具有设置cookie的适当报头。

我需要将后续请求视为授权请求,因为尝试了以下选项,但似乎都不起作用。它被拒绝,状态代码为401。

使用userid和密码的第一个呼叫,响应状态为200

const userDoc = {
userId: 'test-user-1',
userName: 'Test User 1',
emailId: 'test.user.1@abc.xom',
password: 'test-password'
} ;
let resp
resp = await axios({method : 'post', url : 'http://localhost:4040/auth/local', data : {userId: userDoc.userId, password: userDoc.password },withCredentials: true   })

以下选项用于发送下一个请求

  1. 发送作为第一次请求的一部分接收的cookie

    const headers = { headers : {Cookie: resp.headers['set-cookie'][0] } };
    
  2. 作为第一个请求的一部分接收时发送标头

    const headers = { headers : resp.headers};
    
  3. 将CCD_ 1与上述报头一起发送。

使用上述任一选项进行第二次调用

resp = await axios({method : 'post', url : 'http://localhost:4040/v1/master/account', data : accountDoc , headers, withCredentials: true})
  1. 使用httpAgent,与axios实例保持活动
const axios = require('axios')
const http = require("http")
const httpAgent = new http.Agent({keepAlive : true , timeout :1000})
const instance = axios.create({httpAgent})
const resp1 = await instance({method : 'post', url : 'http://localhost:4040/auth/local', data : {userId: userDoc.userId, password: userDoc.password, } , withCredentials: true })
const resp2 = await instance({method : 'post', url : 'http://localhost:4040/v1/master/account', data : accountDoc , withCredentials: true })

已拒绝,状态代码为401

--   Error: Request failed with status code 401
at createError (/home/Projects/FinAccounts2003/node_modules/axios/lib/core/createError.js:16:15)
at settle (/home/Projects/FinAccounts2003/node_modules/axios/lib/core/settle.js:17:12)
at IncomingMessage.handleStreamEnd (/home/Projects/FinAccounts2003/node_modules/axios/lib/adapters/http.js:269:11)
at IncomingMessage.emit (events.js:412:35)
at endReadableNT (internal/streams/readable.js:1334:12)
at processTicksAndRejections (internal/process/task_queues.js:82:21)

服务器代码是标准的passport-js本地代码,与浏览器配合良好。

它可能是一些问题的重复,给出的解决方案是1(withCredentials: true,上面已经尝试过了2(Authorization: Bearer ${token}-在这种情况下不适用,在passport js中,cookie是直接设置的,并且没有获得令牌。

对我有效的一个解决方案是使用模块强硬cookie和axios cookiejar支持。我将它们组合在一个persistent-client.js文件中,然后我就可以维护请求之间的会话(commonJS(:

const axios = require('axios').default;
const { CookieJar } = require('tough-cookie');
const { wrapper } = require('axios-cookiejar-support');
module.exports = function () {
const jar = new CookieJar();
const client = wrapper(axios.create({ jar }));
return client;
}

有两种不同的方式将会话授权令牌从服务器发送到客户端(web浏览器(

  1. 通过(HttpOnly(响应标头
  2. 通过响应机构

有两种不同的方式来授权客户端请求(将会话令牌从web浏览器发送到服务器。(

A。自动:HttpOnly标头

B。手动:Authorization: Bearer [TOKEN]

通常方法1和方法A一起使用,方法2和方法B一起使用。我认为你把它们混淆了。

如果服务器使用Set-Cookie发送会话令牌,那么我认为浏览器会在未来的所有请求中自动发送会话令牌(到同一域(。

您能确认set-cookie标头的实际内容来自服务器吗?请注意,如果这些是HttpOnlycookie,您可能无法通过JS进行检查;检查开发控制台";"网络";您还可以检查是否从";应用程序";选项卡

如果客户端确实需要通过标头手动发送令牌,则标头需要适合特定的Authorizationcookie格式。(你没有这么做。你只是在回显从服务器收到的标题。(

请参阅我对类似问题的回答。

我认为您不应该为此使用任何第三方软件包,尤其是当他们使用javascript(这是XSS安全漏洞(直接访问cookie时。Cookies应使用securewithCredentials: true0设置,并且决不能直接使用Document.cookie访问。

  • 请确保passport确实设置了您的cookie,并且您在登录时正确地发回了cookie。请验证是否已在浏览器中进行了设置。

  • 请确保您在express中启用了CORS,指定了要从中发出请求的域,并在CORS中启用了凭据。

  • 确保您在axios请求中使用withCredentials

  • 请确保已使用正确的域和路径设置cookie。

最新更新