Skip to content

Commit 1684729

Browse files
authored
refactor: cookie support via interceptors (#216)
* Removes axios-cookiejar-support dependency. * Adds cookie-support.ts for providing interceptors to interact with tough-cookie. * Updates cookiejar tests.
1 parent 03a091a commit 1684729

File tree

5 files changed

+269
-97
lines changed

5 files changed

+269
-97
lines changed

lib/cookie-support.ts

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/**
2+
* (C) Copyright IBM Corp. 2022.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import extend from 'extend';
18+
import { AxiosRequestConfig, AxiosResponse } from 'axios';
19+
import { Cookie, CookieJar } from 'tough-cookie';
20+
import logger from './logger';
21+
22+
export class CookieInterceptor {
23+
private readonly cookieJar: CookieJar;
24+
25+
constructor(cookieJar: CookieJar | boolean) {
26+
if (cookieJar) {
27+
if (cookieJar === true) {
28+
logger.debug('CookieInterceptor: creating new CookieJar');
29+
this.cookieJar = new CookieJar();
30+
} else {
31+
logger.debug('CookieInterceptor: using supplied CookieJar');
32+
this.cookieJar = cookieJar;
33+
}
34+
} else {
35+
throw new Error('Must supply a cookie jar or true.');
36+
}
37+
}
38+
39+
public async requestInterceptor(config: AxiosRequestConfig) {
40+
logger.debug('CookieInterceptor: intercepting request');
41+
if (config && config.url) {
42+
logger.debug(`CookieInterceptor: getting cookies for: ${config.url}`);
43+
const cookieHeaderValue = await this.cookieJar.getCookieString(config.url);
44+
if (cookieHeaderValue) {
45+
logger.debug('CookieInterceptor: setting cookie header');
46+
const cookieHeader = { cookie: cookieHeaderValue };
47+
config.headers = extend(true, {}, config.headers, cookieHeader);
48+
} else {
49+
logger.debug(`CookieInterceptor: no cookies for: ${config.url}`);
50+
}
51+
} else {
52+
logger.debug('CookieInterceptor: no request URL.');
53+
}
54+
return config;
55+
}
56+
57+
public async responseInterceptor(response: AxiosResponse) {
58+
logger.debug('CookieInterceptor: intercepting response.');
59+
if (response && response.headers) {
60+
logger.debug('CookieInterceptor: checking for set-cookie headers.');
61+
const cookies: string[] = response.headers['set-cookie'];
62+
if (cookies) {
63+
logger.debug(`CookieInterceptor: setting cookies in jar for URL ${response.config.url}.`);
64+
// Write cookies sequentially by chaining the promises in a reduce
65+
await cookies.reduce(
66+
(cookiePromise: Promise<Cookie>, cookie: string) =>
67+
cookiePromise.then(() => this.cookieJar.setCookie(cookie, response.config.url)),
68+
Promise.resolve(null)
69+
);
70+
} else {
71+
logger.debug('CookieInterceptor: no set-cookie headers.');
72+
}
73+
} else {
74+
logger.debug('CookieInterceptor: no response headers.');
75+
}
76+
return response;
77+
}
78+
}

lib/request-wrapper.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* eslint-disable class-methods-use-this */
22

33
/**
4-
* (C) Copyright IBM Corp. 2014, 2021.
4+
* (C) Copyright IBM Corp. 2014, 2022.
55
*
66
* Licensed under the Apache License, Version 2.0 (the "License");
77
* you may not use this file except in compliance with the License.
@@ -18,8 +18,6 @@
1818

1919
import axios, { AxiosInstance, AxiosRequestConfig } from 'axios';
2020
import * as rax from 'retry-axios';
21-
22-
import axiosCookieJarSupport from 'axios-cookiejar-support';
2321
import extend from 'extend';
2422
import FormData from 'form-data';
2523
import { OutgoingHttpHeaders } from 'http';
@@ -36,6 +34,7 @@ import {
3634
} from './helper';
3735
import logger from './logger';
3836
import { streamToPromise } from './stream-to-promise';
37+
import { CookieInterceptor } from './cookie-support';
3938

4039
/**
4140
* Retry configuration options.
@@ -102,10 +101,13 @@ export class RequestWrapper {
102101

103102
// if a cookie jar is provided, wrap the axios instance and update defaults
104103
if (axiosOptions.jar) {
105-
axiosCookieJarSupport(this.axiosInstance);
106-
107104
this.axiosInstance.defaults.withCredentials = true;
108-
this.axiosInstance.defaults.jar = axiosOptions.jar;
105+
const cookieInterceptor = new CookieInterceptor(axiosOptions.jar);
106+
const requestCookieInterceptor = (config) => cookieInterceptor.requestInterceptor(config);
107+
const responseCookieInterceptor = (response) =>
108+
cookieInterceptor.responseInterceptor(response);
109+
this.axiosInstance.interceptors.request.use(requestCookieInterceptor);
110+
this.axiosInstance.interceptors.response.use(responseCookieInterceptor);
109111
}
110112

111113
// get retry config properties and conditionally enable retries

package-lock.json

Lines changed: 0 additions & 56 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@
7777
"@types/node": "~10.14.19",
7878
"@types/tough-cookie": "^4.0.0",
7979
"axios": "^0.26.1",
80-
"axios-cookiejar-support": "^1.0.0",
8180
"camelcase": "^5.3.1",
8281
"debug": "^4.1.1",
8382
"dotenv": "^6.2.0",

0 commit comments

Comments
 (0)