jwilsson / spotify-web-api-php

A PHP wrapper for Spotify's Web API.
MIT License
867 stars 156 forks source link

IPv6 endpoint with err 403 #242

Closed onlsol closed 2 years ago

onlsol commented 2 years ago

Although the endpoints for accounts/api.spotify.com claim to support IPv6 and resolve the DNS with both options, it looks like only the endpoint via IPv4 allows auth and api usage.

# e.g. on a new Ubuntu hosts that prefers IPv6
curl -s -o /dev/null -w "%{http_code}"  'https://accounts.spotify.com/authorize'
403 # rejected

# for reproducing on hosts that prefer IPv4, enforcing to resolve the domain to the IPv6 address
curl -s -o /dev/null -w "%{http_code}"  'https://accounts.spotify.com/authorize' --resolve 'accounts.spotify.com:443:2600:1901:1:c36::'
403 # rejected

# ensuring IPv4 usage 
curl -s -o /dev/null -w "%{http_code}"  'https://accounts.spotify.com/authorize' --resolve 'accounts.spotify.com:443:35.186.224.25'
303 # OK, allows auth

Is the issue known and does the PHP library have an option to enforce sticking to the IPv4? As workaround, I'd suggest

if (defined('CURLOPT_IPRESOLVE') && defined('CURL_IPRESOLVE_V4')) {
   curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
}
sjerdo commented 2 years ago

Is this an issue on Ubuntu systems only? I don't experience any problems with the Spotify API using IPv6 on MacOS.

~ % dig +short A accounts.spotify.com
edge-web-split-geo.dual-gslb.spotify.com.
35.186.224.25
~ % dig +short AAAA accounts.spotify.com
edge-web-split-geo.dual-gslb.spotify.com.
2600:1901:1:c36::
~ % curl -4 -s -o /dev/null -w "%{http_code}" 'https://accounts.spotify.com/authorize'
303%
~ % curl -6 -s -o /dev/null -w "%{http_code}" 'https://accounts.spotify.com/authorize'
303%   
jwilsson commented 2 years ago

Hey! I'm afraid I cannot reproduce this on neither one of Ubuntu nor macOS. There is however support for setting custom cURL options if you want to.

For example:

$request = new SpotifyWebAPI\Request(
    'curl_options' => [
        CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4,
    ],
]);

// Then, pass the $request when instantiating Session and SpotifyWebAPI
$session = new SpotifyWebAPI\Session(
    'CLIENT_ID',
    'CLIENT_SECRET',
    'REDIRECT_URI',
    $request
);

$api = new SpotifyWebAPI\SpotifyWebAPI([], null, $request);
onlsol commented 2 years ago

@jwilsson resolved by your proposal CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4 which sticks to resolving ipv4 only - even if ipv6 is preferred by the environment though broken or missing DNS records (AAAA) for the sub domains.

thanks!