LuanRT / YouTube.js

A JavaScript client for YouTube's private API, known as InnerTube.
https://ytjs.dev
MIT License
3.51k stars 220 forks source link

10.2.0 Unauthenticated response when using a cookie #707

Open dnicolson opened 2 months ago

dnicolson commented 2 months ago

Steps to reproduce

  1. Run this after copying the cookie from YouTube:
const youtube = await Innertube.create({
    cookie: 'xxx',
});

console.log(await youtube.getPlaylists())

Failure Logs

throw new InnertubeError(`Request to ${response.url} failed with status ${response.status}`, yield response.text());
            ^

InnertubeError: Request to https://www.youtube.com/youtubei/v1/browse?prettyPrint=false&alt=json failed with status 401
    at HTTPClient.<anonymous> (<path>)
    at Generator.next (<anonymous>)
    at fulfilled (/Users/dave/Workspace/node_modules/tslib/tslib.js:166:62)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  info: '{\n' +
    '  "error": {\n' +
    '    "code": 401,\n' +
    '    "message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",\n' +
    '    "errors": [\n' +
    '      {\n' +
    '        "message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",\n' +
    '        "domain": "global",\n' +
    '        "reason": "unauthorized"\n' +
    '      }\n' +
    '    ],\n' +
    '    "status": "UNAUTHENTICATED"\n' +
    '  }\n' +
    '}\n',
  date: 2024-07-27T20:29:11.248Z,
  version: '10.2.0'
}

Expected behavior

The cookie should function similarly to OAuth authentication.

Current behavior

As documented in #703, there is a difference between no cookies, invalid cookies, and authentic cookies. This doesn't appear to be the case for all endpoints though.

When running in the browser with a Userscript there is no issue. It's not clear what is different as the headers and payload look comparable.

Version

Default

Anything else?

No response

Checklist

LuanRT commented 2 months ago

The cookies from your browser get rotated after a few minutes, thus becoming invalid. Nothing can be done about that unfortunately.

dnicolson commented 2 months ago

It doesn't seem to be a cookie expiration issue, as the immediate use of cookies also fails. Instead, it appears that browser mechanisms are preventing external clients.

Cookies work in the yt-playlists-delete-enhancer Userscript and I assume the Subscribe to YouTube Playlists browser extension.

It is still interesting that valid browser cookies will give a more populated getHistory() response, seemingly validating the cookie but not entirely.

dnicolson commented 1 month ago

Cookies can work, but these two keys need to be manually copied because they are HttpOnly:

If these keys are appended to the document.cookie value, requests from Node.js are possible.

Requests from a Userscript or extension on youtube.com work with just document.cookie though.

I wonder if this is documented anywhere, or if it should be?