Koa: using crypto with koa 2

Created on 22 Mar 2017  路  4Comments  路  Source: koajs/koa

When I am trying to use node crypto example with koa2 context behave like it would be lost

router.get('/password', (ctx, next) => {

  const crypto = require('crypto');
  crypto.pbkdf2('secret', 'salt', 100000, 512, 'sha512', (err, key) => {
    if (err) throw err

    const hex = key.toString('hex')

    ctx.status = 200
    ctx.body = hex

    console.log(hex)  // '3745e48...aa39b34'
  })
})

I have got error:

assert.js:81
 throw new assert.AssertionError({
 ^
 AssertionError: headers have already been sent
 at Object.set status [as status] (/code/node_modules/koa/lib/response.js:82:5)
 at Object.status (/code/node_modules/delegates/index.js:92:31)
 at InternalFieldObject.crypto.pbkdf2 [as ondone] (/code/code/routes.js:13:24)

If I wont set ctx.status = 200 inside pbkdf2 then I got 404 Not Found default response

Any idea of this behavior?

question

Most helpful comment

Or you should wrap the async method in a promise, then you can await it.

Maybe something like this:

const crypto = require('crypto');

function generatePassword(secret, salt) {
  return new Promise((resolve, reject) => {
    crypto.pbkdf2(secret, salt, 100000, 512, 'sha512', (err, key) => {
      if (err) {
        reject(err)
      } else {
        resolve(key.toString('hex'))
      }
    })
  })
}

router.get('/password', async (ctx, next) => {
  const hex = await generatePassword('secret', 'salt')
  ctx.status = 200
  ctx.body = hex
  console.log(hex)  // '3745e48...aa39b34'
})

All 4 comments

I think u have to use the synchronous version of pbkdf2. I've not really tested it.

router.get('/password', (ctx, next) => {
  const crypto = require('crypto');
  const key = crypto.pbkdf2('secret', 'salt', 100000, 512, 'sha512');
  ctx.status = 200;
  ctx.body = key.toString('hex');
})

Or you should wrap the async method in a promise, then you can await it.

Maybe something like this:

const crypto = require('crypto');

function generatePassword(secret, salt) {
  return new Promise((resolve, reject) => {
    crypto.pbkdf2(secret, salt, 100000, 512, 'sha512', (err, key) => {
      if (err) {
        reject(err)
      } else {
        resolve(key.toString('hex'))
      }
    })
  })
}

router.get('/password', async (ctx, next) => {
  const hex = await generatePassword('secret', 'salt')
  ctx.status = 200
  ctx.body = hex
  console.log(hex)  // '3745e48...aa39b34'
})

like that manually or use https://github.com/normalize/mz to get promise version of pbkdf2

@dicearr sync version works but it freezies node thread while calculating

@slaskis worked, thanks!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

wlingke picture wlingke  路  3Comments

coodoo picture coodoo  路  4Comments

TheRav3n picture TheRav3n  路  3Comments

tracker1 picture tracker1  路  3Comments

SteveCruise picture SteveCruise  路  3Comments