request/request-promise

Behavior inconsistency with `request` re: `tough-cookie` integration

ScottyMJacobson opened this issue ยท 20 comments

Normally I'd try to dig more for an explanation, but I'm a bit confounded here. I'm doing some cookie construction / management by hand via tough-cookie to maintain sessions for my API calls, and it looks like request and request-promise are giving me two different behaviors, where request works but request-promise does not.

The problematic code is as follows

const request = require('request');
const requestPromise = require('request-promise');
const tough = require('tough-cookie');

let sessionCookie = new tough.Cookie({
    key: "some_key",
    value: "some_value",
    domain: 'api.mydomain.com',
    httpOnly: true,
    maxAge: 31536000
});
let cookiejar = request.jar();
cookiejar.setCookie(sessionCookie, 'https://api.mydomain.com'); // does not throw an error


let sessionCookie2 = new tough.Cookie({
    key: "some_key",
    value: "some_value",
    domain: 'api.mydomain.com',
    httpOnly: true,
    maxAge: 31536000
});
let cookiejar2 = requestPromise.jar();
cookiejar2.setCookie(sessionCookie2, 'https://api.mydomain.com'); // TypeError: str.trim is not a function

Is it just a version/dependency thing? Am I just abusing the concept of cookie jars beyond repair?
From my package.json:

    "request": "^2.81.0",
    "request-promise": "^4.2.0",
    "tough-cookie": "^2.3.2",

I'm leaving the request.jar() patch in for now, but I'd love to know what's going wrong exactly

Thanks in advance,
Scotty

Thanks for making it easy for me to reproduce the issue @ScottyMJacobson ! This one haunted me a while back already.

When you use request-promise there are two different Cookie prototypes in play and tough-cookie derails. There is nothing you can do. I am working on a fix inside of request-promise.

I just published request-promise@4.2.1 which includes the fix. Thanks again for bringing this up!

Now I am trying to use request-promise@4.2.1 to generate cookiejar
like let cookiejar2 = requestPromise.jar(); but it still occur this problem,why?

thanks a lot

@frejus123 Could you post your code snippet to help me understand your situation?

@frejus123 If you use the same code as shown in the README then most likely you have tough-cookie installed multiple times. Please run npm ls tough-cookie to verify that and make sure you have it installed only once.

@analog-nico
Thanks analog-nico a lot.By using npm ls tough-cookie:

โ”œโ”€โ”ฌ request-promise@4.2.1
โ”‚ โ””โ”€โ”€ tough-cookie@2.3.2 (A)
โ””โ”€โ”€ tough-cookie@2.3.2 (B)

I found I really have installed tough-cooke twice,then I delete one tough-cookie marked as (B).
When I run again ,it occur tough is not defined

``

`
var rp = require('request-promise');
var tough = require('tough-cookie');

var cookie = new tough.Cookie({
key: tssKey,
value: tssVal,
//domain: 'localhost',
httpOnly: true,
maxAge: 31536000
});
var cookiejar = rp.jar();
cookiejar.setCookie(cookie, 'http://localhost:8080');
var requestOptions = {
method: 'POST',
uri: 'http://localhost:8080/sss',
body:jsonStr,
headers: {
'content-type': 'application/json;charset=UTF-8'
},

resolveWithFullResponse:

true,
jar: cookiejar
};`

@frejus123 If you delete A instead of B then it should work. This then also resembles the packages hierarchy when you do a clean npm install.

@analog-nico
Thanks a lot, it's resolved. #

@frejus123 Excellent. I'll add a note to the README for people who experience the same issue as you just did. Happy coding!

I am having the same problem as @ScottyMJacobson I am using exactly same code.

screen shot 2018-05-24 at 4 34 15 pm
And getting the same error:

TypeError: str.trim is not a function

Any clue, I am using request-promise@4.2.2

My code looks like this:

let cookie = new tough.Cookie({domain: '.companyName.ninja',
  httpOnly: true,
  name: '_application_session',
  path: '/',
  secure: false,
  value: 'f044888d39e2d19126716d9f54028700' })
let cookieJar = request.jar()
cookieJar.setCookie(cookie, 'http://application.companyName.ninja/')
options.jar = cookieJar

Like @kapilchokhawala, I started getting this error again (I'm not sure whether it was triggered by a new version of one of the relevant packages). This time, the error happened even when I used let jar = request.jar(); (which seems to have been the workaround I had found last year, using the non-promise request lib)

The solution over in this request issue thread seemed to have worked, but feels a bit brittle to dig into the internals of request / tough-cookie

            let toughCookieJar = new tough.CookieJar(undefined, {looseMode: true});
            let jar = request.jar();
            jar._jar = toughCookieJar;
            jar.setCookie(cookieObject, endpoints.base);

I bumped into this problem, solved by downgrading packages for now:

    "request": "^2.85.0",
    "request-promise": "^4.2.2",
    "tough-cookie": "^2.3.4"

(this was the wrong config, happened to work due to other unrelated things)

@mfonsen after some poking around with versions, it looks like for me as well tough-cookie 2.3.4 (and the others) are the last version that I can get to work

@analog-nico this appears to have broken the unit tests for this lib and requests-promise-native (the lib we're actually using) - let me know if you'd like me to open an issue in that repo as well

I'm also getting the same error msg after upgrading from 2.3.4 to 2.4.2:
TypeError: str.trim is not a function

at Function.parse (node_modules/request/node_modules/tough-cookie/lib/cookie.js:428:13)
      at CookieJar.setCookie (node_modules/request/node_modules/tough-cookie/lib/cookie.js:1004:21)
      at CookieJar.setCookieSync (node_modules/request/node_modules/tough-cookie/lib/cookie.js:1395:18)
      at RequestJar.setCookie (node_modules/request/lib/cookies.js:25:20)

Actually, the problem seems to be in the request pkg. Upgrading request from 2.83.0 to 2.87.0 breaks tough-cookie / jar process. I downgraded request back to 2.83.0 and things are working now.

โ”œโ”€โ”ฌ request@2.87.0
โ”‚ โ””โ”€โ”€ tough-cookie@2.3.4
โ”œโ”€โ”ฌ request-promise-native@1.0.5
โ”‚ โ””โ”€โ”€ tough-cookie@2.3.4  deduped
โ””โ”€โ”€ tough-cookie@2.3.4
vs:

โ”œโ”€โ”ฌ request@2.83.0
โ”‚ โ””โ”€โ”€ UNMET DEPENDENCY tough-cookie@~2.3.3
โ”œโ”€โ”ฌ request-promise-native@1.0.5
โ”‚ โ””โ”€โ”€ tough-cookie@2.4.2  deduped
โ””โ”€โ”€ tough-cookie@2.4.2

Same here with this

const cookieJar = rp.jar();
const cookie: request.Cookie | string = request.cookie(cookieDetails.toString()) || '';
cookieJar.setCookie(cookie, `https://${ domain }`);

Yet, replacing the last 2 lines with:
cookieJar.setCookie(cookieDetails.toString(), `https://${ domain }`);

seems to solve this. ๐Ÿคจ

The problem is not solved yet.


+-- request@2.83.0
| -- tough-cookie@2.3.4 +-- request-promise@4.2.1 | -- tough-cookie@2.4.2 deduped
`-- tough-cookie@2.4.2


The Version Work for me.
"request": "^2.81.0",
"request-promise": "^4.2.1",
"tough-cookie": "2.3.2",

Instead of using tough-cookie, I am directly setting cookie in the options/header for the request-promise. It works for me.

cookieJar.setCookie(cookie.toString(), https://${ domain });

toString(). It's work for me

Clean install, using the exact code from the example, and this still occurs for me

i just fixed like this:

let cookie = new tough.Cookie({
        key: "key",
        value: value,
        domain: 'http://test.com',
        httpOnly: true,
        maxAge: 31536000
    });
    let cookie_str = cookie.toString();

    cookie_str = cookie_str.replace('Domain=http://test.com;', '');

    let cookiejar = rp.jar();
    cookiejar.setCookie(cookie_str, 'http://test.com');

it worked. ^V^