1

When I post to the server, regardless of the information I give the auth function, it returns true. My hunch is that I am trying to do something synchronously, that is asynchronous in nature, but I don't know how to fix it.

auth = (username, api_key, device) ->
  hashed_key = hash.sha256(username + api_key + device, salt) 
  winston.debug('Checking auth for ' + username)
  redis_client.get hashed_key, (err, data) ->
    if data == username
        true

# Main Handler for posting data for a device.
server.post "/:customer/:site/:device", create = (req, res, next) ->
    message = JSON.parse(req.body)
    winston.info(server.name + ': Recieved event from ' + req.params.device)
    authenticated = auth(message.username, message.api_key, message.device)
    winston.debug('****' + authenticated)
    if authenticated == true 
        winston.debug('Auth passed, got a valid user/device/api combination: ' + message.username)
        redis_client.publish('device_events', req.body)
        return next()
    else
        winston.debug('Auth failed, cant find device ' + message.device + ' for ' + message.username)
        return next(restify.NotAuthorizedError)
Ben Hughes
  • 2,527
  • 1
  • 18
  • 16
  • Riddle me this; if you add an else false in auth, does its behavior change? – Menztrual Apr 30 '12 at 07:11
  • No - makes no difference, which makes me think that auth is true as its a function declaration, but its either not getting executed, or doesn't complete in time...... – Ben Hughes Apr 30 '12 at 10:15
  • 1
    Your hunch is correct. Your `auth` function will return *before* `redis_client.get` has executed -- that's why it takes a callback. You can't return from a callback, as you're no longer in the same scope. See [this answer](http://stackoverflow.com/questions/9310855/get-and-get-value/9310916#9310916) of mine for a similar situation and [this answer](http://stackoverflow.com/questions/9362823/why-is-a-function-and-a-callback-non-blocking-in-node-js/9363071#9363071) for an explanation of why one would use this paradigm. – Linus Thiel Apr 30 '12 at 11:10

1 Answers1

1

If you know (or have a hunch) that something is asynchronous, you should pass what to do afterward as a callback function. I'm not sure how your server's post function is working, though if it's like Node HTTP's request you should do something like the following:

get = (location, callback, retriever, filterer, formatter)->
  decoratedCallback = (data)->
    callback formatter.applyFormat filterer.applyFilter data
  retriever.retrieve location, decoratedCallback

module.exports = get
  • Thanks for your reply - I'm a coffee/node newbie (using restify) so I'm not sure I understand :| I am python guy. Its more the order of execution I don't understand..... – Ben Hughes Apr 30 '12 at 10:13
  • Ah. Saying that you use restify helps. If you want auth to fire synchronously, you may need to use node-sync. You may also want to consider breaking your functions down into smaller chunks such that you can pass auth as next(), have that take a call back which does the logging and publishes events, etc etc – Visionary Software Solutions Apr 30 '12 at 10:40