gr2m / helpdesk

Answering all your GitHub API/automation questions live on Twitch
https://twitch.tv/gregorcodes
Creative Commons Zero v1.0 Universal
22 stars 11 forks source link

Help with Octokit Oauth using `access_token` #41

Closed ganning127 closed 3 years ago

ganning127 commented 3 years ago

I'm building a GitHub app, and I'm trying to authenticate Octokit using an Oauth access_token that I'm getting when the user clicks sign in with Github

The access_token I'm using has access to the repo scope, but when I try to authenticate Octokit with this token, I get: HttpError: A JSON web token could not be decoded

Here is my code:

let TOKEN = "<Token>"

const appOctokit = new Octokit({
    auth: TOKEN
});

I've also tried authenticating like this:

const appOctokit = new Octokit({
        authStrategy: createOAuthAppAuth,
        auth: {
            clientId: "<Client_ID>",
            clientSecret: "<Client_Secret>",
        },
});

but when I do that, and I try deleting an issue using octokit, I get an HttpError: Not Found error.

gr2m commented 3 years ago

Hey Ganning,

yeah OAuth can be hella confusing.

Can you share the code on how you are retrieving the access_token? What is your use case?

I'm building a GitHub app, and I'm trying to authenticate Octokit using an Oauth access_token that I'm getting when the user clicks sign in with Github

The access_token I'm using has access to the repo scope, but when I try to authenticate Octokit with this token, I get: HttpError: A JSON web token could not be decoded

So a things seem to get mixed up here. You say you created a GitHub App, but then say the access token has the repo scope. However, GitHub apps don't use scopes, only OAuth Apps.

The A JSON web token could not be decoded error message suggests that you are attempting to send a request that requires GitHub App authentication (REST API routes starting with /app)

ganning127 commented 3 years ago

Shoot so sorry, I meant I was creating an Oauth App. The app should be able to close and open issues.

Here is my code:

var path = __dirname;
const { Octokit } = require("@octokit/rest");
const {
  createOAuthAppAuth,
  createOAuthUserAuth,
} = require("@octokit/auth-oauth-app");
const { createAppAuth } = require("@octokit/auth-app");

var express = require("express"),
  app = express(),
  config = require("./config.js")
port = 9292;
var router = express.Router();
var fetch = require('node-fetch');

app.set('view engine', 'ejs');
app.set('views', __dirname);

app.use('/', router);
app.use('/assets', express.static(path + '/assets'))

var githubOAuth = require('github-oauth')({
  githubClient: config.GITHUB_KEY,
  githubSecret: config.GITHUB_SECRET,
  baseURL: 'http://localhost:' + port,
  loginURI: '/auth/github',
  callbackURI: '/auth/github/callback',
  scope: 'repo'
})

router.get('/', function (req, res) {
  res.sendFile(path + '/pages/index.html');
});

router.get("/auth/github", function (req, res) {
  console.log("started oauth");
  return githubOAuth.login(req, res);
});

router.get("/auth/github/callback", function (req, res) {
  console.log("received callback");
  // res.sendFile(path + '/pages/form.html');
  return githubOAuth.callback(req, res);
});

githubOAuth.on('error', function (err) {
  console.error('there was a login error', err)
})

githubOAuth.on('token', function (token, serverResponse) {

  async function main() {
    const access_token = JSON.stringify(token.access_token)

    console.log(access_token)

    const appOctokit = new Octokit({
      auth: access_token
    });

    const {
      data: { slug },
    } = await appOctokit.rest.apps.getAuthenticated();

    const owner = "ganning127"
    const repo = "test1"

    await appOctokit.rest.issues.create({
      owner,
      repo,
      title: "Hello world from " + slug,
    });

  }
  serverResponse.end(JSON.stringify(token))

  main();

})

var server = app.listen(port, function () {
  console.log('Listening on port %d', server.address().port);
});
gr2m commented 3 years ago

you import createAppAuth but you don't use it anywhere, and that one is for GitHub Apps anyway.

You use github-oauth which is very old and probably dysfunctional, definitely not feature complete. I recommend you have a look at https://github.com/octokit/oauth-app.js/

appOctokit.rest.apps.getAuthenticated() is an endpoint for GitHub Apps, not OAuth Apps, that's were you get your error message from.

I know this is all rather confusing and we don't have a proper documentation to lay out all the Octokit functionality. The best we got so far is https://github.com/octokit/octokit.js/, I recommend you go through that, especially the OAuth section.

Let me know if that helps.

ganning127 commented 3 years ago

yeah, i had alot of modules on there I wasn't using cause I was just testing different solutions to see if they would work lol

so I took a look at the links you sent and this is the code I have so far:

const app = new OAuthApp({
  clientType: "oauth-app",
  clientId: config.GITHUB_KEY,
  clientSecret: config.GITHUB_SECRET,
  scopes: [
    "repo"
  ]
});

app.on("token", async ({ token, octokit }) => {
  const { data } = await octokit.request("GET /user");

  console.log(token);
  console.log(`Token retrieved for ${data.login}`);

  console.log(octokit.auth)

  let owner = "ganning127"
  let repo = "test33"
  let issue_number = 5;
  let info = await octokit.request('POST /repos/{owner}/{repo}/issues', {
    owner,
    repo,
    title: "DSFD"
  })

  console.log(info)

});

I'm not sure how to add the repo scope to the Oauth app here. The error this gives is Not Found. Is there any way I can add repo scope?

ganning127 commented 3 years ago

Actually, I just figured it out, the links you sent were very helpful. Thank you so much for your help!

gr2m commented 3 years ago

Glad I could help? Can you share what was most confusing/most helpful? I wonder if there are some simple improvements we can do to make it clearer for the future

ganning127 commented 3 years ago

I think the most confusing part for me was when I was looking at auth in these docs: https://octokit.github.io/rest.js/v18#authentication

From reading the OAuth Apps: authenticate using user access token created by an OAuth app, to which you granted selected permissions, or as the OAuth App itself (OAuth using client_id and client_secret). Learn more about the optional @octokit/auth-oauth-app authentication strategy, I was lead to this page, which didn't have the info that worked for me (in the links that you sent)