2

I'm running a small Angular application with a Node/Express backend.

In one of my Angular factories (i.e. on the client side) I make a $http request to Github to return user info. However, a Github-generated key (which is meant to be kept secret) is required to do this.

I know I can't use process.env.XYZ on the client side. I'm wondering how I could keep this api key a secret? Do I have to make the request on the back end instead? If so, how do I transfer the returned Github data to the front end?

Sorry if this seems simplistic but I am a relative novice, so any clear responses with code examples would be much appreciated. Thank you

gwpmad
  • 91
  • 1
  • 7

1 Answers1

2

Unfortunately you have to proxy the request on your backend to keep the key secret. (I am assuming that you need some user data that is unavailable via an unauthenticated request like https://api.github.com/users/rsp?callback=foo because otherwise you wouldn't need to use API keys in the first place - but you didn't say specifically what you need to do so it is just my guess).

What you can do is something like this: In your backend you can add a new route for your frontend just for getting the info. It can do whatever you need - using or not any secret API keys, verify the request, process the response before returning to your client etc.

Example:

var app = require('express')();

app.get('/github-user/:user', function (req, res) {
    getUser(req.params.user, function (err, data) {
        if (err) res.json({error: "Some error"});
        else res.json(data);
    });
});

function getUser(user, callback) {
    // a stub function that should do something more
    if (!user) callback("Error");
    else callback(null, {user:user, name:"The user "+user});
}

app.listen(3000, function () {
  console.log('Listening on port 3000');
});

In this example you can get the user info at:

The function getUser should make an actual request to GitHub and before you call it you can change if that is really your frontend that is making the request e.g. by cheching the "Referer" header or other things, validate the input etc.

Now, if you only need a public info then you may be able to use a public JSON-P API like this - an example using jQuery to make things simple:

var user = prompt("User name:");
var req = $.getJSON('https://api.github.com/users/'+user);
req.then(function (data) {
  console.log(data);
});

See DEMO

rsp
  • 91,898
  • 19
  • 176
  • 156
  • Thanks for your response - I'm just pulling in repositories under my name so perhaps I don't need the API key after all! I had the faint idea that the key meant that more requests could be made. But I'm probably wrong then. Either way I would really appreciate your example! – gwpmad Jun 11 '16 at 10:33
  • @gwpmad You're right that more requests can be made with authenticated requests - in that case you need to proxy your request on the backend to hide your keys. – rsp Jun 11 '16 at 10:48
  • Ah excellent thanks. This looks like the way to go. I'll try it out, using the https library from Node – gwpmad Jun 11 '16 at 11:23
  • Managed to get this working using the principle in your top example, and then using $http on my Angular factory to call backend endpoint. Thanks a lot!! – gwpmad Jun 11 '16 at 12:07