JWT Auth middleware always returns 401

Hello everyone! I’m trying to implement jwt authentication in my project. I have config/auth.js set-up to use jwt. The login works correctly and generates the token:

token = await auth.withRefreshToken().attempt(username, password)

{ type: ‘bearer’,
token: ‘eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOjIsImlhdCI6MTUyNzUzMDY4NSwiZXhwIjoxNTI3NTM0Mjg1fQ.IGftFqoGDuo5_RbpVJHjj
EQHWOyskYxiOsnmwESH-VE’,
refreshToken: ‘2847c3f7e55a74f0667f32ede6c0cee0WN0ZA1ZYBO67RzEmkB3BFsv4XfAfxLrlQSn2cAAJQ5zAmVJK++cQayWxruCubl2E’ }

which I send to the client (vue spa) as a cookie:

response.cookie(‘Authorization’, token, {
path: ‘/’
})

In the browser, I see the Authorization header with the following value:

Authorization=3c9d102753c20ddcb3c14dc0902a4647HQzcz0f4UWydrS6UlCOb9PreD7CSF0PMsSpgNCTO7ewOI7vmd0VxQPsh1746GQ4JGYvqcmMKc%2F%2FrC6eh9i5YGye00nJlhYsUiydCYbhGXYGMVkGlGSKOhFpwQKI6o2lUdAfyB%2F5DwqOwJbK8nHlB619%2B5gVbHok%2B5xMnBm6Smf2er50siYhs%2FMzxjZ420Vv%2B0YeOE20XiMAw0WOwda6de%2B7jMw%2FkV6bEO00Tx9pnGDJkGyLyMZnTKMtnZPilu5o5jyxKGvvmpBMcGSMMUAmiW1kuL9QDYiTxky9Av4YhmgKed%2BEViyo%2FLBF9x5Ikmd3mVyQksciRL4MLYegxHVf%2F7RAxSovETVtCOIhG9Gok0Nxle4XQUuQF1P%2FEWWlosKNPLZw8hfFOaDFWRNr0mJhgXD%2FrYWQEDhLXjo7qZlZcml2%2FYToRmQlBmGLS41GeYkNa5JXOzBeu6wY3UIOxRJ%2BzcQ%3D%3D; Path=/

I know that the jwt token is encrypted before sent to the client and all subsequent requests send back this encrypted value, but my protected routes always throw 401. This is one of my route configurations:

Route.get('/articles', 'ArticleController.getArticles')
      .middleware('auth:jwt')

I’m not sure what’s missing. Any ideas? Thanks in advance!

1 Like

I’m not familiar with setting a token as a cookie, but I think you need to set the token in the header like this:

The idea behind sending the jwt as a cookie was that I didn’t have to manually store it somewhere and manually send it back as a header. Moreover there are security advantages to using a httpOnly cookie to pass the token.
Anyway, I’ll just do it the old fashioned way :stuck_out_tongue:
Thanks!

@radu: hi there,
Did you find way to make it work with cookie? I really don’t want to store token in localstorage.

The jwt middle-ware checks for Authorization Bearer <token>as @patrickdronk has said. So the client side would have to send this in the request headers. But since you are using cookies, you may have to override the default implementation that jwt auth middle-ware uses to check authorization. You can add an extra middle that checks if the request has the token cookie, then you can add it to the headers so that jwt auth will now be able to find it. You can use the example below:

"use strict";
/** @typedef {import('@adonisjs/framework/src/Request')} Request */
/** @typedef {import('@adonisjs/framework/src/Response')} Response */
/** @typedef {import('@adonisjs/framework/src/View')} View */

class AuthSetHeader {
  /**
   * @param {object} ctx
   * @param {Request} ctx.request
   * @param {Function} next
   */
  async handle({ request }, next) {
    // call next to advance the request
    const token = request.cookie("token");

    if (token) {
      request.request.headers["authorization"] = `Bearer ${token}`;
    }
    await next();
  }
}

module.exports = AuthSetHeader;