Email not appearing in Twitch OIDC userinfo response

I’m working on a Spring Boot application that needs to connect with Twitch using OIDC authentication. The problem is that when I make a request to get user information, the email field is always missing from the response.

From what I found in Twitch’s documentation, you need to explicitly request email data by adding a claims parameter to the authorization request. The documentation says to include a JSON object with userinfo and id_token fields to specify which claims you want.

I created a custom resolver to handle this:

public class TwitchAuthRequestResolver implements OAuth2AuthorizationRequestResolver {
    private final OAuth2AuthorizationRequestResolver baseResolver;

    public TwitchAuthRequestResolver(ClientRegistrationRepository repository) {
        this.baseResolver = new DefaultOAuth2AuthorizationRequestResolver(repository, "/oauth2/authorization");
    }

    @Override
    public OAuth2AuthorizationRequest resolve(HttpServletRequest httpRequest) {
        OAuth2AuthorizationRequest request = baseResolver.resolve(httpRequest);
        return request != null ? modifyAuthRequest(request) : null;
    }

    @Override
    public OAuth2AuthorizationRequest resolve(HttpServletRequest httpRequest, String registrationId) {
        OAuth2AuthorizationRequest request = baseResolver.resolve(httpRequest, registrationId);
        return request != null ? modifyAuthRequest(request) : null;
    }

    private OAuth2AuthorizationRequest modifyAuthRequest(OAuth2AuthorizationRequest originalRequest) {
        Map<String, Object> extraParams = new LinkedHashMap<>(originalRequest.getAdditionalParameters());
        extraParams.put("claims", "%7B%22userinfo%22%3A%7B%22email%22%3Anull%2C%22picture%22%3Anull%7D%2C%22id_token%22%3A%7B%22email_verified%22%3Anull%7D%7D");

        return OAuth2AuthorizationRequest.from(originalRequest)
                .additionalParameters(extraParams)
                .build();
    }
}

My configuration looks like this:

spring:
  security:
    oauth2:
      client:
        registration:
          twitch:
            provider: twitch
            client-id: my-client-id
            client-secret: my-secret
            client-authentication-method: 'client_secret_post'
            redirect-uri: http://localhost:9000/login/oauth2/code/twitch
            scope:
              - openid
              - user:read:email
            authorization-grant-type: authorization_code
            clientName: Twitch Login
        provider:
          twitch:
            authorization-uri: https://id.twitch.tv/oauth2/authorize
            tokenUri: https://id.twitch.tv/oauth2/token
            userInfoUri: https://id.twitch.tv/oauth2/userinfo
            jwkSetUri: https://id.twitch.tv/oauth2/keys
            user-name-attribute: preferred_username

I can see that the claims parameter is being added to the authorization URL, but the userinfo endpoint still doesn’t include the email in its response. What am I missing here?

check if email permissions are enabled for your twitch app in the dev console. had the same problem - wasn’t the code at all. twitch needs explicit email access at the app level even when your scopes are right. log the userinfo response body to see what’s actually coming back. that’ll tell you why the email’s missing.

Had the same problem. Your URL encoding in the claims parameter is probably messing things up. Don’t manually encode the JSON string - build it dynamically instead. Double-check your Twitch app settings too. Make sure the redirect URI matches and email access is enabled in your dashboard. What worked for me was opening the browser’s network tab and checking the actual authorization URL. You can see if the claims parameter looks right. Sometimes double encoding breaks everything. Try a simpler claims structure first - just request email without picture and email_verified to narrow down the issue. One more thing: Twitch won’t return email info unless the user has a verified email address, even with correct scopes and claims.

The problem’s probably how you’re building the claims parameter. Don’t hardcode the URL-encoded string - build the JSON object programmatically and let Spring handle encoding. I hit something similar and Twitch’s OIDC can be really picky about claims format. Also check your Twitch app config in their developer console. Even with correct scopes and claims, if your app isn’t set to request email data or your redirect URI doesn’t match exactly, Twitch will just silently drop the email field. Use your browser’s dev tools to check the actual OAuth flow. Look at the authorization request URL and make sure the claims parameter’s being sent right. Sometimes it’s not the userinfo response that’s broken - it’s how the initial authorization request is formatted. The user:read:email scope won’t work without the claims parameter being processed correctly by Twitch’s auth server.

This topic was automatically closed 4 days after the last reply. New replies are no longer allowed.