Search code examples
node.jsgithubgithub-apiaxiosgist

How to post a gist via the API (not anonymously)


I'm using passport-github strategy.

passport.use(new Strategy({
    clientID: "...",
    clientSecret: "...",
    callbackURL: 'http://localhost:3000/login/github/return',
    scope: 'gist'
  },
  function(accessToken, refreshToken, profile, cb) {
    return cb(null, profile);
  }));

Then I make the POST request

app.get('/profile/post',
  require('connect-ensure-login').ensureLoggedIn(),
  function(req, res){
var url = 'https://api.github.com/gists';

axios.post(url, {
  method: "POST",
  "description": "POSTING FROM EXPRESS",
  "public": true,
  "files": {
    "file1.txt": {
      "content": "EXPRESS "
    }

}
})
  .then(function (response) {...})
  .catch(function (error) { ... });

The gist gets created but anonymously.

I tried passing "owner" and "user" as part of the request arguments but no use. I also tried passing the username in the url

As far as I can see the docs say nothing about this.


Solution

  • You have to store the access token you get from passport authentication callback. For instance, using mongo with mongoose to store the user :

    passport.use(new GitHubStrategy({
            clientID: "...",
            clientSecret: "...",
            callbackURL: 'http://localhost:3000/login/github/return'
        },
        function(accessToken, refreshToken, profile, done) {
    
            process.nextTick(function() {
    
                User.findOne({ id: profile.id }, function(err, res) {
                    if (err)
                        return done(err);
                    if (res) {
                        console.log("user exists");
                        return done(null, res);
                    } else {
                        console.log("insert user");
                        var user = new User({
                            id: profile.id,
                            access_token: accessToken,
                            refresh_token: refreshToken
                        });
                        user.save(function(err) {
                            if (err)
                                return done(err);
                            return done(null, user);
                        });
                    }
                })
            });
        }
    ));
    

    Then when you deserialize the user, you get the user back with the access token :

    passport.serializeUser(function(user, done) {
        done(null, user.id);
    });
    
    passport.deserializeUser(function(id, done) {
        User.findOne({ "id": id }, function(err, user) {
            done(err, user);
        });
    });
    

    and now in your endpoint, put req.user.access_token in Authorization header of github API request :

    app.get('/profile/post', 
      require('connect-ensure-login').ensureLoggedIn(),
      function(req, res) {
    
        axios.post('https://api.github.com/gists', {
          "method": "POST",
          "description": "POSTING FROM EXPRESS",
          "headers": {
            "Authorization" : "token " + req.user.access_token
          },
          "public": true,
          "files": {
            "file1.txt": {
              "content": "EXPRESS "
            }
          }
        })
        .then(function (response) {...})
        .catch(function (error) { ... });
      }
    );
    

    But instead of building the request manually, you can use octonode library that do it for you. You can find a complete example here of passport-github with octonode and mongodb