ytmusicapi icon indicating copy to clipboard operation
ytmusicapi copied to clipboard

Proper authentication

Open sigma67 opened this issue 4 years ago • 14 comments

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 avatar Apr 22 '20 16:04 sigma67

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 :+1:

FranciscodeMaussion avatar May 03 '20 21:05 FranciscodeMaussion

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.

sigma67 avatar May 03 '20 21:05 sigma67

(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.

simon-weber avatar May 04 '20 19:05 simon-weber

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?

sigma67 avatar May 04 '20 19:05 sigma67

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.

simon-weber avatar May 04 '20 20:05 simon-weber

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?

sigma67 avatar May 05 '20 11:05 sigma67

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.

simon-weber avatar May 05 '20 17:05 simon-weber

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.

ndg63276 avatar Jun 19 '20 22:06 ndg63276

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

Takoooooo avatar Jul 02 '20 10:07 Takoooooo

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.

stboch avatar Oct 13 '20 11:10 stboch

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

nero12 avatar Sep 06 '21 10:09 nero12

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

sigma67 avatar Sep 06 '21 13:09 sigma67

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 avatar Oct 01 '21 19:10 salsaman

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

salsaman avatar Oct 01 '21 19:10 salsaman

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?

SiboutVanLoo avatar Mar 18 '23 21:03 SiboutVanLoo

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!!

vixalien avatar Mar 24 '23 09:03 vixalien

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.

sigma67 avatar Mar 24 '23 09:03 sigma67

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 avatar Mar 24 '23 10:03 vixalien

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)

vixalien avatar Mar 24 '23 10:03 vixalien

@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?

sigma67 avatar Apr 02 '23 08:04 sigma67

@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 :)

vixalien avatar Apr 02 '23 11:04 vixalien

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?

sigma67 avatar Apr 02 '23 12:04 sigma67

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

vixalien avatar Apr 02 '23 12:04 vixalien

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

sigma67 avatar Apr 02 '23 15:04 sigma67

oh okay then.

vixalien avatar Apr 02 '23 16:04 vixalien

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.

sigma67 avatar Apr 05 '23 19:04 sigma67

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

vixalien avatar Apr 05 '23 20:04 vixalien