pilcrowonpaper / oslo

A collection of auth-related utilities
https://oslo.js.org
MIT License
1.06k stars 35 forks source link

get error on google.validateAuthorizationCode(code, codeVerifier) #87

Open anatoliy-t7 opened 3 months ago

anatoliy-t7 commented 3 months ago

Hi. I am getting an error on Google validateAuthorizationCode

103 |         // providers are allowed to return non-400 status code for errors
104 |         if (!("access_token" in result) && "error" in result) {
                                      ^
TypeError: result is not an Object. (evaluating '"access_token" in result')
      at /.../node_modules/arctic/node_modules/oslo/dist/oauth2/index.js:104:33
body URLSearchParams {
  "code": "4/0Acv..................",
  "client_id": "6441.............",
  "grant_type": "authorization_code",
  "redirect_uri": "http://localhost:3000/api/oauth/google/callback",
  "code_verifier": "NPQBRq................",
  "client_secret": "GO....................",
}

What did I do wrong?

Thanks.

vargamartonaron commented 1 month ago

I get the same error using the Google class. With the GitHub class, I had json parsing error since github returned 404 for the request. The .validateAuthorizationCode needs review. I suggest writing a manual fetch with your client id, secret, code according to Google's API requirements. Here is my implementation to get the token: Note that the codeVerifier might be redundant.

async function exchangeCodeForToken(code: string, codeVerifier: string) {
  const response = await fetch('https://oauth2.googleapis.com/token', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
      'Accept': 'application/json',
    },
    body: new URLSearchParams({
      client_id: googleClientId,
      client_secret: googleClientSecret,
      code: code,
      code_verifier: codeVerifier,
      redirect_uri: googleRedirectUri,
      grant_type: 'authorization_code'
    }),
  });

  if (!response.ok) {
    throw new Error(`Error: ${response.statusText}`);
  }

  try {
    const data = await response.json();

    if (data && "access_token" in data) {
      const tokens = data.access_token;
      return tokens;
    } else if (data && "error" in data) {
      console.error('Error:', data.error, data.error_description);
    } else {
      console.error('Unexpected result:', data);
    }
  } catch (error) {
    console.error('Failed to parse response as JSON:', error)
  }
}