保存axios登录凭证,以便在nodejs中进行后续调用

7rtdyuoh  于 5个月前  发布在  iOS
关注(0)|答案(2)|浏览(77)

我正在尝试使用axios登录到网络上的帐户,
网站将返回一个cookie。
Axios应该存储此cookie。
之后,每当我打电话到这个网站时,它都会发送这个cookie来验证它是否登录。
我在网上搜索了一下,发现withCredentials: true选项可以做到这一点。
不过,我试过了,但不管用。
在示例中,即使在步骤1中我成功登录,
当我尝试创建一个用户时,它显示失败。
如果你查看失败消息的响应HTML,你会看到它把你送回了登录页面,所以它认为你没有登录。
请使用我提供的代码沙箱示例来查看真实的示例。

import axios from 'axios'

const examlpeHost = 'http://radmandemo.dmasoftlab.com'

const axiosInstance = axios.create({
  baseURL: examlpeHost,
  withCredentials: true,
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
  },
})

// * Step 1. Login:

const loginEnpoint = '/admin.php?cont=login'
const loginRes = await axiosInstance.post(loginEnpoint, {
  managername: 'admin',
  password: '1111',
  md5: '27780bc84ff5136090c9b33063c0d38f', // password
})
// check to see if login successful based on the returned html
const loginResHtml = loginRes.data
const isSuccessLogin = loginResHtml.includes(
  `<META http-equiv="refresh" content="0;URL=admin.php">`
)
if (isSuccessLogin) console.log('[success ✅] login successful!')
else throw new Error('[fail ❌] Login failed!')

// * Step 2. create user:
const createUserEndpoint = '/admin.php?cont=store_user'
const createUserRes = await axiosInstance.post(createUserEndpoint, {
  username: 'test_user123456789',
  password1: '1111',
  password2: '1111',
  srvid: 0,
})
// check to see if create user successful based on the returned html
const createUserResHtml = createUserRes.data
const isSuccessCreateUser = createUserResHtml.includes('Account registered')
if (isSuccessCreateUser) console.log('[success ✅] create user successful!')
else console.log('[fail ❌] create user failed!')

字符串
View on Code Sandbox


的数据
我做错了什么?当我使用superagent时,它对我有效,但现在在axios中它不起作用。

wqnecbli

wqnecbli1#

根据Axios源代码,他们只是绕过了XHR请求的withCredentials标志,这意味着Node.JS适配器实现不支持这部分功能。
我想有一个很简单的方法可以满足你的需求

实现Axios拦截器

这个想法是写拦截器:
1.响应拦截器,用于捕获响应中的set-cookie标头,提取cookie并存储它们。
1.当cookie被存储时设置cookie的请求拦截器。
下面是一个简单的拦截器实现:

// Cookies in a map format, e.g {session: "xxyyzz"}
const cookies = {};

// Request interceptor. Set cookies if there are some.
const setCookies = (config) => {
    if (Object.keys(cookies).length) {
        // Format cookies string, e.g "session=xxyyzz; token=123"
        const cookiesStr = Object.keys(cookies).map((key) => `${key}=${cookies[key]}`).join('; ');

        config.headers['Cookie'] = cookieStr;
    }
    return config;
}

// Response interceptor. Extract cookies and store them.
const extractCookies = (config) => {
    if (config.headers['set-cookie']) {
        // Parse cookies headers, e.g {'set-cookie': [{session: "xxyyzz; ..."}]}
        config.headers['set-cookie'].forEach((cookie) => {
            const [key, value] = cookie.split(';')[0].split('=');
            cookies[key] = value;
        });
    }
    return config;
};

字符串
您可以通过以下方式使用此拦截器:

// Globally, for all Axios requests
axios.interceptors.response.use(setCookies);
axios.interceptors.response.use(extractCookies);

// For the specific instance
const axiosInstance = axios.create({...});
axiosInstance.interceptors.request.use(setCookie);
axiosInstance.interceptors.response.use(extractCookies);


注意:这是一种非常简单的方法。理想情况下,解决方案应该考虑cookie TTL,域和路径。
我希望它能回答你的问题。如果我需要澄清什么,请告诉我。

2wnc66cl

2wnc66cl2#

感谢@Phil,我使用这个axios-cookiejar-support包来解决这个问题:

$ npm install axios
$ npm install tough-cookie
$ npm install axios-cookiejar-support

个字符

相关问题