Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proper authentication #10

Closed
sigma67 opened this issue Apr 22, 2020 · 27 comments · Fixed by #371
Closed

Proper authentication #10

sigma67 opened this issue Apr 22, 2020 · 27 comments · Fixed by #371
Assignees
Labels
enhancement New feature or request
Milestone

Comments

@sigma67
Copy link
Owner

sigma67 commented Apr 22, 2020

For authenticated requests, this API currently depends on the browser session that the sesson cookie originates from. If the browser session is invalidated (logout, account switch, expiry), the app will fail to authenticate without a new browser cookie (see also #7).

Ideally this API should have a way to create and renew such a cookie independently. This could be done by providing the user with a link to login, similar to gmusicapi, and storing the provided cookie. As for renewal I'm not sure how this could work, but perhaps it can be reverse engineered from the web app.

Since I am completely unfamiliar with YouTube authentication, I hope someone can help out with this.

@sigma67 sigma67 added enhancement New feature or request help wanted Extra attention is needed labels Apr 22, 2020
@FranciscodeMaussion
Copy link

Here you have some help from google
I was going to do it myself, but I have discovered they already have a python kind of api.
Maybe I will be back but not now. :) good luck 👍

@sigma67
Copy link
Owner Author

sigma67 commented May 3, 2020

Thanks for the hint. I'm aware of the Data API, but unfortunately it has pretty low quotas (10,000 units and a search costs 100 units). That's why I created this project.

Authentication for the Data API is done using OAuth, but I don't think you can use those credentials for YouTube Music. At least I don't know how.

@simon-weber
Copy link

(Francisco sent me an email about this thread)

It might be worth checking if Youtube Music has a similar auth story to Play Music. iOS or Android traffic ought to work, though I'd expect iOS to be simpler since it wouldn't be using the Google Play OAuth services stuff.

@sigma67
Copy link
Owner Author

sigma67 commented May 4, 2020

Unfortunately I don't have access to an iPhone to test. I do have an Android device though. Any good pointers for getting started with Android traffic capturing?

@simon-weber
Copy link

I usually do it with a debugging proxy like fiddler, burp, charles, etc. In theory it just requires running the proxy on a computer, then configure your android device to use it + trust the cert. Here's fiddler's intructions. If it's working for other apps but not the one you're looking at, there's probably some kind of cert pinning going on.

It looks like some other folks have mostly reversed it already, eg https://gist.github.com/leptos-null/5ae739d2a561f5d1910fd9af3bb8a945. There's even a python client in the works here. It looks like it uses a private oauth app + some kind of custom signing of request bodies.

@sigma67
Copy link
Owner Author

sigma67 commented May 5, 2020

Thanks for the helpful insights. tombulled has done great work translating the reverse engineered part to Python. There's also a PHP implementation here.

They use hardcoded Project and API keys and only support public endpoints right now, see i.e. tombulled's project.

For authenticated requests you need an oauth refresh access token, which leptos-null extracts from a Mac Device with the Keychain Access.app. I guess now the question is how you can obtain a private refresh token in a simpler fashion that works on all systems.

Perhaps its possible to reuse gmusicapi session code for this?

@simon-weber
Copy link

Gotcha. I'd bet it's doing a normal OAuth flow and that someone has already captured what we need: the scope and client creds. gmusicapi has an example of this, I think from the Google Music android app. From there we should be able to plug it into any old oauth library to try it out.

@sigma67 sigma67 added this to the 1.0 milestone May 27, 2020
@ndg63276
Copy link

Hey, I built an unofficial Alexa skill based on Simon's work with google music (https://github.com/ndg63276/alexa-google-music). I'd love to build the equivalent with Youtube Music, but obviously it's a lot simpler if a user just has to put in a username and app password, rather than an oauth flow. So if that's possible, I'd love that.

I will have a look to see if there is anything else I can do to help.

@Takoooooo
Copy link

To authentificate properly you will need only "__Secure-3PSID" cookie and "__Secure-3PAPISID" cookie.I get them from CefSharp(embedded browser for desktop applications) and Authorization header and correct body.Another cookies may cause even 400 errors if you put any of them incorrectly\with wrong value.Theoretically you could even get those cookies from google chrome cookie storage\another browser storage

@stboch
Copy link

stboch commented Oct 13, 2020

Unless google has implemented a new method this is the only valid method, same one used by the locationsharinglib (google maps api) since in 2019 they started preventing non-human browser based authentication scraping.

@nero12
Copy link

nero12 commented Sep 6, 2021

is work still going on with integrating API authentication, to avoid using header request ?

@sigma67
Copy link
Owner Author

sigma67 commented Sep 6, 2021

I am not currently actively working on it, but open toward a PR/suggestions for implementation

@salsaman
Copy link

salsaman commented Oct 1, 2021

Not sure how useful it is, but the Nest setup for Home Assistant has a step by step for setting up OAuth, in that case for the devices API.

https://www.home-assistant.io/integrations/nest/

@salsaman
Copy link

salsaman commented Oct 1, 2021

I am sure you are already aware but it is also possible to enable "Application Passwords" in Google account settings.

@SiboutVanLoo
Copy link

Or, google should open up the sdk commands to allow media control too.
Desperatly trying to find a workaround since the latest "no media found issue"... (-.-')
Any progress here?

@vixalien
Copy link

vixalien commented Mar 24, 2023

hey @sigma67. I have found a viable authentication method, as used by my deno/typescript library muse (which is hugely insipired by ytmusicapi and can almost be considered a port)

it involves using the same way of authenticating as the youtube tv website.

here's how to get youtube tv's credentials:

  1. change your user agent to [Your current useragent] Cobalt/Version (just add "Cobalt/Version" to the user agent)
  2. Go to youtube.com/tv
  3. Choose to login with code (Don't actually log in, just check out the devtools for the requests)
  4. In the DevTools, you'll see a request to https://www.youtube.com/o/oauth2/device/code endpoints. Get the client_id and scope details from there. This device returns a login code
  5. You'll also see a couple of requests to https://www.youtube.com/o/oauth2/token which is the youtube website polling the server to check if the user has authenticated.

I have used this implementation in my library (linked above) and I use it to successfully authenticate users.

https://github.com/vixalien/muse/blob/f953285f5bd7c194e937452157ec4d1b749ac3a0/auth.ts#L87-L147

I would also like to answer some problems on how it works exactly. thanks for making this library!!

@sigma67
Copy link
Owner Author

sigma67 commented Mar 24, 2023

Hi, that looks like a really nice project and a lot of work, I hope it takes off.

I think the auth part can serve as a good blueprint for an implementation in ytmusicapi. I'll have to take a closer look some time soon.

@vixalien
Copy link

thanks! but to be honest, it was inspired by ytmusicapi, and I think it wouldn't have happened if ytmusicapi didn't exist. thanks to you and to all the contributors.

I'm happy to answer any questions regarding the auth mechanism if any help is needed

@vixalien
Copy link

also it's important to note that the other authentication methods the YouTube TV website uses can also be implemented. this is including:

  • login via Wi-Fi
  • login via TV code
  • login via Google login (using the TV interface though, using the TV keyboard)

@sigma67
Copy link
Owner Author

sigma67 commented Apr 2, 2023

@vixalien where are you getting CLIENT_ID and CLIENT_SECRET from?

Do all users use the same values? Would this result in hitting API limits once your library is adopted by more users?

@vixalien
Copy link

vixalien commented Apr 2, 2023

@sigma67 as I said above, you can get client id and client secret by looking at the requests the YouTube TV website sends.

I think the endpoints are something like /oauth/token and /oauth/code (im not on my PC rn to verify)

you can find those values in the request body.

as to the ratelimits, as these are the keys of the YouTube TV client, it has no limit (same reason you never see a rate limit when you use the YouTube app) as innertube thinks the traffic is coming directly from YouTube TV. the only issue will be when YouTube decides to rotate or block these keys...

another issue is that currently, you won't be able to upload tracks using the TV client's keys as it doesn't have access to that scope :)

@sigma67
Copy link
Owner Author

sigma67 commented Apr 2, 2023

Ah good to know. That's an interesting limitation. All other endpoints work for you like library, history? Can you get upload data from the library?

@vixalien
Copy link

vixalien commented Apr 2, 2023

yep the other endpoints work. even deleting uploads works. it can probably be fixed by supplying in additional scopes when authenticating lol

@sigma67 sigma67 self-assigned this Apr 2, 2023
@sigma67
Copy link
Owner Author

sigma67 commented Apr 2, 2023

I don't think it's possible at all with this OAuth flow: https://developers.google.com/identity/protocols/oauth2/limited-input-device#allowedscopes

@vixalien
Copy link

vixalien commented Apr 2, 2023

oh okay then.

@sigma67 sigma67 linked a pull request Apr 4, 2023 that will close this issue
@sigma67 sigma67 removed the help wanted Extra attention is needed label Apr 4, 2023
sigma67 added a commit that referenced this issue Apr 4, 2023
@sigma67
Copy link
Owner Author

sigma67 commented Apr 5, 2023

I experimented a bit with using YouTube Data API client_secrets.json to obtain the access token.

Gist to obtain oauth.json is here.

Using the credentials I ran into the following error when trying to do a library search with the obtained token:

Exception: Server returned HTTP 403: Forbidden.
YouTube Internal API (InnerTube) has not been used in project 123456789 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/youtubei.googleapis.com/overview?project=123456789 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.

Since the link is a dead end, it seems the InnerTube API required for YTMusic is just not accessible publicly without using public API keys like those for web or TV, where it has been enabled.

@vixalien
Copy link

vixalien commented Apr 5, 2023

yep exactly. Google is very good at scoping keys to different projects

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants