thephpleague / oauth2-github

GitHub Provider for the OAuth 2.0 Client
MIT License
106 stars 29 forks source link

Get e-mail address #3

Closed mindplay-dk closed 8 years ago

mindplay-dk commented 8 years ago

I was surprised to find that GitHub doesn't reveal the user's e-mail address as part of the profile itself - it appears the email field on the profile is null, maybe because GitHub defaults to also making your primary e-mail address private (?)

I found this older PR which implemented this:

https://github.com/thephpleague/oauth2-client/pull/189

Did the GitHub provider in this library start from scratch, rather than from the existing provider?

Or how come this feature isn't there?

stevenmaguire commented 8 years ago

Hi @mindplay-dk. Sorry for the delay in response. This provider did not start from scratch and it was updated alongside the underlying package. It is true that there was previously a getUserEmails method available. However, the focus of the package, and this provider, is to help you obtain access tokens on behalf of resource owners.

With that said, the underlying package was updated to include a tool that should help you in your specific goal here. It now includes the getAuthenticatedRequest method which should prove useful in obtaining user emails and data from any other Github API endpoints.

$request = $provider->getAuthenticatedRequest(
    'GET', 
    'https://api.github.com/user/emails', 
    $token // Your access token
);

$response = $provider->getHttpClient()->send($request);

I hope this helps.

mindplay-dk commented 8 years ago

Oh, I see, this actually requires you to go beyond the OAuth API to the GitHub API - so it's beyond the scope of an OAuth client. Gotcha.

I wonder how come GitHub don't expose basic profile data like your email address via OAuth like most other providers?

stevenmaguire commented 8 years ago

That is it exactly. The previous version of the package slipped into a gray area between OAuth flow and API client; the package is not meant to be an API client. The getAuthenticatedRequest is, I feel, a good compromise.

Every OAuth provider is different, annoyingly so sometimes. I am sure they have a reason and I'm not sure if that reason is public.

Shall we close this issue?

philsturgeon commented 8 years ago

Twitter don't either. Lots of sites don't because "connect with this account" can lead to spam they don't want. That's why quite a few sites ask you to sign up and connect your account, but then ask for your email too.

Phil Sturgeon Sent from my iPhone and there's probably typos because I'm probably at the pub.

On Jan 8, 2016, at 2:17 AM, Rasmus Schultz notifications@github.com wrote:

Oh, I see, this actually requires you to go beyond the OAuth API to the GitHub API - so it's beyond the scope of an OAuth client. Gotcha.

I wonder how come GitHub don't expose basic profile data like your email address via OAuth like most other providers?

— Reply to this email directly or view it on GitHub.

mindplay-dk commented 8 years ago

Lots of sites don't

Yeah, but GitHub does - they just don't do it within the OAuth protocol. If they weren't exposing email addresses at all, I'd buy that they're protecting their users info - but it doesn't explain why they would break protocol.

Anyway, yeah, we can close this issue.

craigh commented 8 years ago

how do I get the emails from

$response = $provider->getHttpClient()->send($request);

?

$response is an instance of Psr\Http\Message\ResponseInterface but I cannot figure out how to obtain the response as indicated in the github api docs (https://developer.github.com/v3/users/emails/#response) because it appears to be a stream which I don't understand 😢

shadowhand commented 8 years ago

@craigh the response is a PSR-7 object. You should be able to do:

$request = $provider->getAuthenticatedRequest(...);
$emails = $provider->getResponse($request);

And not worry about using getHttpClient at all.

craigh commented 8 years ago

Thank you so much! I'm slowly learning ;-)

m-nienberg commented 8 years ago

I think it would be very helpful to include this in the sample Authorization Code Flow. Everyone trying to retrieve a user's email address is going to face this issue.

wuestkamp commented 4 years ago

The issue is if Github users have no public email address specified. To still get the emails from the user this works for me:

'scope' => [
    'public_profile',
    'user:email',
],
$client = $this->clientRegistry->getClient($clientName);
$token = $client->getAccessToken();
$provider = $client->getOAuth2Provider();
$request = $provider->getAuthenticatedRequest(
    'GET',
    'https://api.github.com/user/emails',
    $token
);
$array = $provider->getParsedResponse($request);
foreach ($array as $item) {
    if ($item['primary'] === true) {
        $email = $item['email'];
        break;
    }
}

// important to use same token and not $oauthResource = $client->fetchUser();
$oauthResource = $client->fetchUserFromToken($token);
$name = $oauthResource->getName();
testlinkOAuth commented 4 years ago

I can confirm that is the user in GitHub configures his/her profile with Public email you do not need additional code.