spring-attic / spring-social-github

Github API binding and connect support.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

spring-social-github can't get user email

decisionwanted opened this issue · comments

I'm using spring-social/spring-social-github in order to authenticate user through GitHub in my Spring Boot web application.

In order to sign in user I have created following html form:

<form action="http://example.com/auth/github" method="POST">
 <input name="scope" value="user,gist" type="hidden">
 <button type="submit">Sign in with GitHub</button>
</form>

everything works fine except I can't get user email address.

According to GitHub documentation https://developer.github.com/v3/oauth/#scopes GitHub OAuth API user scope includes user:email and user:follow.

What can be wrong ?

The problem is that this library uses following https://api.github.com/user endpoint in order to get user profile. That endpoint returns the public email address for the user, and users don't need to specify a public email address. So, if the user doesn't have a public email address defined -- you get a null value back.

The https://api.github.com/user/emails endpoint returns the private list of email addresses and that list should always have at least one address.

if it possible to extend spring-social-github library in order to call https://api.github.com/user/emails endpoint for user email address ?

Right now I'm unable override GitHubTemplate.initSubApis() in order to initialize my own version of UserTemplate.getUserProfile() because GitHub Template.initSubApis is private method..

My StackOverflow issue for this one: http://stackoverflow.com/questions/29986218/spring-social-github-cant-get-user-email

@decisionwanted

Maybe this can help. Have a look at UsersTemplate, operations on email are supported.

Improvements? Issues and PRs are welcome.

One Email has a primary flag, I'd expect to set that one on the UserProfile entity when using fetchUserProfile() in Connection. All other providers already follow that behaviour (set that email when the email scope is added).

Did you manage to find the solution of how to get github user email?

I solved it like this in my project:
@OverRide
public abstract class GithubAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

@value("${github.resource.userInfoUri}")
private String userInfoUri;

public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
...
String token = ((OAuth2AuthenticationDetails) ((OAuth2Authentication) authentication).getDetails()).getTokenValue();
GitHubTemplate github = new GitHubTemplate(token);
LinkedHashMap<String, Object>[] emails = github.getRestTemplate().getForObject(userInfoUri + "/emails", LinkedHashMap[].class);
String email = (String) emails[0].get("email");
...
}

}

which us userInfoUri? https://api.github.com/user ?

Yep : https://api.github.com/user

Be careful, you might get a unverified email address.
I realized during my tests that i had a typo 'gmai.com' in the registered email in github.

I get a 404 doing:

 String token = connection.createData().getAccessToken();
            GitHubTemplate githubTemplate = new GitHubTemplate(token);
            LinkedHashMap<String, Object>[] emails = githubTemplate.getRestTemplate().getForObject("https://api.github.com/user/emails", LinkedHashMap[].class);

Also I get 404 when I try with curl :
curl -H "Authorization: token AUTH-TOKEN https://api.github.com/user/emails
or

curl https://api.github.com/user/emails?access_token=AUTH-TOKEN
using the AUTH-TOKEN I get from above code

solved I was using the wrong scope