How to get access to auth object from outside of the request cycle?


#1

Is it possible to access auth from outside of the request cycle?

Use cases:

  • JWT generation, revocation outside of the request
  • JWT generation during tests, without hitting the endpoint

Thanks.


#2

Hey @moltar! :wave:

Short answer: It depends.

Since Node.js is asynchrone you can handle multiple request at the same time. This is why request isn’t accessible as a global.

What would you want to build for your use cases?


#3

Hm, I am not looking for a global request, that is obviously impossible.

All I want is a global auth object.

A real use case: I need to create a JWT for a user in a test.

A potential future use case: being able to revoke tokens from a cron job.


#4

You need to understand that the auth object is connected to the request object since a User is authenticated for one request (the one he made).

I don’t see where you are stuck with your use cases.


#5

Here’s where I am stuck.

I need to unit test refresh token creation logic. To use a refresh token, I need it created first.

Here’s another use case. Generate a JWT for a random user via CLI.


#6

Another use case, create token that is already expired to test expiration logic.


#7

Yes, it is possible to generate a JWT token outside of the request lifecycle.

But before that.

Unit testing the JWT refresh token logic is not helpful, since the Adonis auth package is responsible for giving the right values and if it doesn’t, then it’s a bug and you should not be concerned with it.

What you want is a normal functional test, that test your app from outside in, which will be part of the normal request/response lifecycle.

My Adonis app at-times have 0 unit tests.


Now the auth object access part

What we really need is a fake instance of Context object and for that to work, we need fake req and res objects, which is possible with the help of node-mocks-http package.

Let’s drop the following code inside start/hooks.js file.

hooks.after.providersBooted(() => {
    ioc.bind('FakeContext', () => {
    	const HttpContext = use('Adonis/Src/HttpContext')
    	const httpMocks = use('node-mocks-http')
    	const req = httpMocks.createRequest({ url: '/' })
    	const res = httpMocks.createResponse()
    	return new HttpContext(req, res)
	})
})

Now you can grab a new instance of context by accessing FakeContext.

const { auth } = use('FakeContext')

And everything will work as expected.

NOTE: Operations performed on Context by Middleware will be missed, since this context is not passed through the middleware chain


#8

I’m specifically trying to test GraphQL mutations for JWT renewal.

Not that I do not trust Adonis and want to test to make sure JWT works. But I just wanted to make sure the mutation itself works when I pass it a refresh token, I want to get a successfully renewed JWT back.

I don’t know how to test that without having a refresh token. I could, of course, use another endpoint to request the JWT and then use that to get a renewal. But I wanted to isolate the test to only renewal and not obtaining the original one.

Thanks for the detailed response. Very helpful!


Using the auth package in another js file