Github Auth: Could not retrieve profile information

Hi,

I am trying to call Github OAuth 2.0 API in Forge. However, there is an error after authorising the Github OAuth app. Forge app fails to retrieve profile information. I guess access token is not properly stored in Forge side.

Error message from Forge in the UI
could not retrieve profile information: {"message":"Bad credentials","documentation_url":"https://docs.github.com/rest","status":"401"}

This is my manifest.url

providers:
  auth:
    - key: github
      name: Github
      remotes:
        - github-base
        - github-api
      scopes:
        - repo
        - user
      type: oauth2
      clientId: Placeholder
      bearerMethod:
        type: authorization-header
      actions:
        authorization:
          remote: github-base
          path: /login/oauth/authorize
        exchange:
          remote: github-base
          path: /login/oauth/access_token
          resolvers:
            accessToken: access_token
        retrieveProfile:
          remote: github-api
          path: /user
          resolvers:
            id: id
            displayName: email
remotes:
  - key: github-api
    baseUrl: https://api.github.com
  - key: github-base
    baseUrl: https://github.com
permissions:
  scopes:
    - read:confluence-groups
  external:
    fetch:
      backend:
        - 'https://api.github.com'
        - 'https://github.com'

Could you please help?

Hi @JonSnow, I can’t see anything noticeably wrong with your configuration. Can you share the code you are using to reproduce the error and the appId?

Hi @BoZhang , I have put the code below

App Id: ari:cloud:ecosystem::app/b30b0055-4cb0-4506-85bd-8f9751a42e5e

frontend/index.jsx

import React, { useState } from 'react';
import ForgeReconciler, { Text, Button } from '@forge/react';
import { invoke } from '@forge/bridge';

const App = () => {
  const [data, setData] = useState(null);

  async function fetch() {
    const result = await invoke('fetchContent');
    setData(result);
  }

  return (
    <>
      <Text>Hello world!</Text>
      <Text>{data ? data : 'Loading...'}</Text>
      <Button onClick={fetch}>Fetch</Button>
    </>
  );
};

ForgeReconciler.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

index.js

import Resolver from '@forge/resolver';
import api from "@forge/api";

const resolver = new Resolver();

resolver.define('fetchContent', async (req) => {
  const github = api.asUser().withProvider('github', 'github-api');

  if (! (await github.hasCredentials())) {
    const result = await github.requestCredentials();
    console.log(result)
  }

  return 'Hehe, world!';
});

export const handler = resolver.getDefinitions();

manifest.yml

modules:
  confluence:globalSettings:
    - key: glboal-settings-example-hello-world-global-settings
      resource: main
      render: native
      resolver:
        function: resolver
      title: glboal-settings-example
  function:
    - key: resolver
      handler: index.handler
      providers:
        auth:
          - github
resources:
  - key: main
    path: src/frontend/index.jsx
remotes:
  - key: github-api
    baseUrl: https://api.github.com
  - key: github-base
    baseUrl: https://github.com
permissions:
  scopes:
    - read:confluence-groups
  external:
    fetch:
      backend:
        - 'https://api.github.com'
        - 'https://github.com'
providers:
  auth:
    - key: github
      name: Github
      remotes:
        - github-base
        - github-api
      scopes:
        - repo
        - user
      type: oauth2
      clientId: Placeholder
      bearerMethod:
        type: authorization-header
      actions:
        authorization:
          remote: github-base
          path: /login/oauth/authorize
        exchange:
          remote: github-base
          path: /login/oauth/access_token
          resolvers:
            accessToken: access_token
        retrieveProfile:
          remote: github-api
          path: /user
          resolvers:
            id: id
            displayName: email
app:
  runtime:
    name: nodejs18.x
  id: ari:cloud:ecosystem::app/b30b0055-4cb0-4506-85bd-8f9751a42e5e

Hi @JonSnow, I had a look at the logs; as suspected, it seems like we were able to exchange for a token successfully, but the token was not good for the API call to retrieve the profile of the connected user.

I configured a Github provider in my app and went through all the steps without any issues, so my suspicion is around your Github OAuth app. Is it possible for you to create another OAuth app and try again?

Also, for your profile retriever config, I found that email is not always returned by the /user API. I replaced it with login instead (which is the username of the user).

2 Likes

Thanks @BoZhang . I created a new OAuth app and it works perfectly. Is there a way to check the logs for debugging this?

1 Like

Hi @JonSnow, unfortunately logs are not available for external auth at the moment. Only the error is returned and displayed on the front end.

I can see how it would be a nice debugging feature. If you’re interested in it, I encourage you to create a feature request on the FRGE board and upvote it.

1 Like