node.jsgithub-apigithub-appoctokit-js

How do you authenticate a GitHub App in Node.js?


I've created a new GitHub App and I'm trying to authenticate from Node. I'm new to GitHub Apps, for example, I don't know what "installationId" is supposed to be. Is that the App ID?

I successfully get a token using a private key, but when I try using the API, I get an error both from Node and from curl.

import { createAppAuth } from '@octokit/auth-app';
import { request } from '@octokit/request';

const privateKey = fs.readFileSync(__dirname + 'file.pem');
const auth = createAppAuth({
 id: 1,
 privateKey,
 installationId: 12345,
 clientId: 'xxx.xxxxxx',
 clientSecret: 'xxxxxx',
});

const appAuthentication = await auth({ type: 'app' });
console.log(`Git repo token: ` + appAuthentication.token);

const result = await request('GET /orgs/:org/repos', {
      headers: {
                 authorization: 'token ' + appAuthentication.token,
               },
               org: 'orgname',
               type: 'public',
      });
return res.status(200).json({ message: 'Git result: ' + result });

Here is the curl example I tried after getting the token from the Node code above.

curl -i -X POST -H "Authorization: Bearer xxxxxxxxxx" -H "Accept: application/vnd.github.machine-man-preview+json" https://api.github.com/app

The result in Node: "Git result: Git repo error: HttpError: Bad credentials"

Result in curl: { "message": "Integration not found", "documentation_url": "https://developer.github.com/v3" }


Solution

  • The JSON Web Token (JWT) authentication can only be used for a few endpoints of GitHub's REST API. Mostly the ones listed on https://developer.github.com/v3/apps/

    For all others, you need an installation access token.

    Can you try this instead?

    const { token } = await auth({ type: "installation" });
    const result = await request("GET /orgs/:org/repos", {
      headers: {
        authorization: "token " + token
      },
      org: "orgname",
      type: "public"
    });
    

    Note that the installationId option must be set to a valid installation ID. You get the installation ID when you install the GitHub app on github.com. For example, you can install the WIP app at https://github.com/apps/wip on your account or any organization you have admin access to. The installation URLs look like this:

    https://github.com/settings/installations/90210

    In the example above, the installation ID is 90210.

    To simplify your code, you can use the auth.hook feature in which case the correct authentication will be set automatically based on the URL

    import { createAppAuth } from "@octokit/auth-app";
    import { request } from "@octokit/request";
    
    const privateKey = fs.readFileSync(__dirname + "file.pem");
    const auth = createAppAuth({
      id: 1,
      privateKey,
      installationId: 12345
    });
    
    const requestWithAuth = request.defaults({
      request: {
        hook: auth.hook
      }
    })
    
    const result = await requestWithAuth("GET /orgs/:org/repos", {
      org: "orgname",
      type: "public"
    });
    

    See https://github.com/octokit/request.js/#authentication for more examples