Invalid Access Token Returned

Hello,

I have a doubt regarding the access token returned by Nylas Auth when using OAuth Access Token flow.

I am trying to intgrate with Google and following are the integrate endpoints for OAuth integrations.

/oauth/login - starts the login flow
/oauth/exchange - exchange code for a access token & refresh token.

    @Get("/oauth/login")
    public ResponseEntity<?> login() {

        List<String> scope = new ArrayList<>();
        scope.add("https://www.googleapis.com/auth/userinfo.email");
        scope.add("https://www.googleapis.com/auth/userinfo.profile");
        scope.add("https://www.googleapis.com/auth/gmail.modify");
        scope.add("https://www.googleapis.com/auth/gmail.compose");
        scope.add("https://www.googleapis.com/auth/calendar");


        UrlForAuthenticationConfig config = new UrlForAuthenticationConfig(NYLAS_CLIENT_ID,
                "http://localhost:9090/oauth/exchange",
                AccessType.OFFLINE,
                AuthProvider.GOOGLE,
                Prompt.DETECT,
                scope,
                true,
                "sQ6vFQN",
                null);

        String url = nylas.auth().urlForOAuth2(config);
        ResponseHeaders headers = ResponseHeaders.builder().status(302).add("location", url).build();
        return ResponseEntity.of(headers);
    }

    @Get("/oauth/exchange")
    public ResponseEntity<?> exchange(@Param("code") String code) {
        assert code != null;
        CodeExchangeRequest codeRequest = new CodeExchangeRequest(
                "http://localhost:9090/oauth/exchange",
                code,
                NYLAS_CLIENT_ID,
                NYLAS_API_KEY,
                null);
        String accessToken = null;
        try{
            CodeExchangeResponse codeResponse = nylas.auth().exchangeCodeForToken(codeRequest);
            accessToken = codeResponse.getAccessToken();
        }catch(Exception e){
            throw new RuntimeException(e);
        }

        ResponseHeaders headers = ResponseHeaders.builder()
                .status(302)
                .add("location", "/")
                .add("set-cookie", "access_token=%s".formatted(accessToken))
                .build();
        return ResponseEntity.of(headers);
    }

I am exchanging the code for a token using the following code.
nylas.auth().exchangeCodeForToken()

The problem is that if I pass the returned token to Google’s endpoint to verify it, I get the invalid token error

curl "https://oauth2.googleapis.com/tokeninfo?access_token=<ACCESS_TOKEN>"
{
  "error": "invalid_token",
  "error_description": "Invalid Value"
}

My questions:

  1. Is the access token returned by Nylas the original access token returned by Google i.e. Nylas ask Google to provide token and returns the same value? Or Nylas keeps the Google returned token to itself & return a different token to the client?
  2. If its the second case, how can I find if the token is valid?

Hello @magg once you had used the token it will became invalid because you already used it. We don’t keep any token. You can find that the token is valid, because the grant is working.

Hey Blag,

I figured it out. The tokens returned by nylas.auth().exchangeCodeForToken() are issued by Nylas, not Google. Below is the snippet of ID token issued which shows that the aud is Nylas.

{
  "at_hash": "_tOCZibY5LPp7b08OWgkAg",
  "aud": "https://api.us.nylas.com/v3",
  "email": "xxxx@xxx.com",
  "exp": 1725514411,
  "family_name": "XXX",
  "given_name": "XXX",
  "iat": 1725510811,
  "iss": "https://nylas.com",
  "name": "XX XXX",
  "provider": "google",
  "sub": "cd7027aa-38a8-47b7-9a63-82e854246ea3"
}

I am using the issued ID token for checking if the token has expired. If yes, then using the refresh token to get the new set of access token & id token.

I verified this using the REST endpoint https://api.us.nylas.com/v3/connect/token

However, I am unable to use Nylas Java SDK to issue the same command. The SDK doesn’t find any method setGrantType() in class CodeExchangeRequest.

image

Hi @magg sorry, I misunderstood your question :frowning: You wanted to check if the token was expired…I thought you wanted to check if it was successfully applied :man_facepalming:t2: Sorry about that :sweat_smile: Regarding the setGrantType() I don’t think any of our SDKs have that kind of method :thinking: