Argon hash driver problem


#1

I have just created a new Adonis project, and decided to switch to the argon hash driver.

I installed argon2, and changed HASH_DRIVER= to argon. After creating signup/login controllers, I signed up a test user with Insomnia.

Everything worked great - I got a JWT back, and I can see the $argon2i$v=19$m=4096 hashed password in mysql database.

However, I then tried to login the test user, with the exact same credentials - and i had this error thrown at me…

{ PasswordMisMatchException: E_PASSWORD_MISMATCH: Cannot verify user password
    at Function.invoke (/media/travis/CC NAS/Projects/alarme/node_modules/@adonisjs/auth/src/Exceptions/index.js:99:19)
    at JwtScheme.invalidPassword (/media/travis/CC NAS/Projects/alarme/node_modules/@adonisjs/auth/src/Schemes/Base.js:275:41)
    at JwtScheme.validate (/media/travis/CC NAS/Projects/alarme/node_modules/@adonisjs/auth/src/Schemes/Base.js:194:18) passwordField: 'password', authScheme: 'jwt' }

So I tried switching back to bcrypt, deleted the user, and tried again - everything works fine this time.

Am I missing something in the docs, or is this a valid bug?


#2

Hey @thetre97! :wave:

That’s a strange issue. I’m using myself the Argon algorithm in production for few months without any issue.

Could you please share some code and also verify that you don’t hash the password twice by mistake?


#3

Hey @romain.lanz :slight_smile:

I had been following this tutorial, and had adapted for my app. See sample code below.

I am new to this (excellent) framework, so I may be making a noob mistake :roll_eyes: :slight_smile:

User Controller:

class UserController {
  async signup ({ request, auth, response }) {
    const userData = request.only([ 'name', 'username', 'email', 'password' ])
    try {
      const user = await User.create(userData)
      const token = await auth.generate(user)

      return response.json({
        status: 'success',
        data: token
      })
    } catch (error) {
      return response.status(400).json({
        status: 'error',
        message: 'There was a problem creating the user, please try again later.'
      })
    }
  }

  async login ({ request, auth, response }) {
    try {
      // validate the user credentials and generate a JWT token
      const token = await auth.attempt(
        request.input('email'),
        request.input('password')
      )

      return response.json({
        status: 'success',
        data: token
      })
    } catch (error) {
      console.log(error)
      response.status(400).json({
        status: 'error',
        message: 'Invalid email/password'
      })
    }
  }
}

User Model:

class User extends Model {
  static boot () {
    super.boot()

    /**
     * A hook to hash the user password before saving
     * it to the database.
     */
    this.addHook('beforeSave', async (userInstance) => {
      if (userInstance.dirty.password) {
        userInstance.password = await Hash.make(userInstance.password)
      }
    })
  }

  /**
   * A relationship on tokens is required for auth to
   * work. Since features like `refreshTokens` or
   * `rememberToken` will be saved inside the
   * tokens table.
   *
   * @method tokens
   *
   * @return {Object}
   */
  tokens () {
    return this.hasMany('App/Models/Token')
  }

  // Alarms Relationship
  alarms () {
    return this.hasMany('App/Models/Alarm')
  }
}

module.exports = User

Routes:

Route.group(() => {
  Route.post('/signup', 'UserController.signup')
  Route.post('/login', 'UserController.login')
}).prefix('auth')

I did yarn add argon2, and I edited .env to HASH_DRIVER=argon, and left hash.js untouched.

Then I posted this JSON to the API /auth/signup route:

{
	"name": "Travis Reynolds",
	"username": "travis",
	"email": "travis@test.com",
	"password": "random123"
}

After posting the exact same thing to the /auth/login route, I get the error from my above message.


#4

Could you please verify that your password has been correctly hashed in your database?

Also, verify that your password field accept 255 characters.