Search code examples
javascriptangularjsnode.jsapiyelp

How can I make this code work without showing my API keys? I am building as app on Node.js/Angular/Express


This code works well with my app but process.env doesn't work from within this function. Is there a way that I can call process.env instead of having to display my keys? If I leave the code as is now, the API call won't work, but if I add my keys it will work. What are my options, or simply why does process.env not work from here as it does on the command line?

function randomString(length, chars) {
    var result = '';
    for (var i = length; i > 0; --i) result += chars[Math.round(Math.random() * (chars.length - 1))];
    return result;
}

var myApp = angular.module('myApp', []);

myApp.controller('MainCtrl', ['$scope', 'MyYelpAPI', '$window', function($scope, MyYelpAPI, $window) {
    $scope.total = [];
    $scope.businesses = [];
    MyYelpAPI.retrieveYelp('', function(data) {
        $scope.businesses = data.businesses
        console.log($scope.businesses)

        var array = $scope.businesses
        var random = Math.floor((Math.random() * array.length) + 1);
        // console.log(array[random])

        var result = array[random]
        console.log(result)

        if (2 > 1) {
            $scope.businesses = [result]
        }
    });

}]).factory("MyYelpAPI", function($http) {
    return {
        "retrieveYelp": function(name, callback) {
            var method = 'GET';
            var url = 'http://api.yelp.com/v2/search?';
            var params = {
                    callback: 'angular.callbacks._0',
                    location: 'New+York',
                    oauth_consumer_key: process.env.yelp_consumer_key, //Consumer Key
                    oauth_token: process.env.yelp_token, //Token
                    oauth_signature_method: "HMAC-SHA1",
                    oauth_timestamp: new Date().getTime(),
                    oauth_nonce: randomString(32, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'),
                    term: 'bakery'
                    // limit: 15
                };
            var consumerSecret = process.env.yelp_consumer_secret; //Consumer Secret
            var tokenSecret = process.env.yelp_token_secret; //Token Secret
            var signature = oauthSignature.generate(method, url, params, consumerSecret, tokenSecret, { encodeSignature: false});
            params['oauth_signature'] = signature;
            $http.jsonp(url, {params: params}).success(callback);
        }
    }
});

Solution

  • You don't have access to process.env on the client side, that's only giving you access to the Node environment. What you should do is move the api call functionality to the server (node) part of your application, and have your angular factory query that endpoint provided by your server code. There, in your server, you can access process.env, and securely store your env key pairs, thus never exposing them to the public.

    A very basic outline (assuming you are developing locally and hosting your api on http://localhost:3000/api may be:

    // client side angular code
    
    .factory("MyYelpAPI", function($http) {
        return {
            "retrieveYelp": function(name, callback) {
                var method = 'GET';
                var url = 'localhost:3000/api/search';
                var params = {
                    ...
                };
    
                ...
    
                $http.jsonp(url, {params: params}).success(callback);
            }
        }
    });
    
    // node/express routing
    
    app.get('/api/search', require('./api.js').search)
    
    // server side i.e. node code (api.js)
    
    module.exports = {
        search: function(req, res) {
            var params = {
                oauth_consumer_key: process.env.yelp_consumer_key, //Consumer Key
                oauth_token: process.env.yelp_token, //Token
            }
    
            ...
    
            res.json(something);
        }
    }