Can we reload the app without losing Auth tokens?

I have been working on a ColdBox app that provides a REST API using JWT for access to the endpoints.

When I am working on new functionality, I frequently need to reload the app so it picks up the changes in my services. However, when I add ?reload=1 to the URL, I lose my auth tokens and I need to log in again and copy the token to the request I am testing.

This has gotten to be quite a pain in the butt.

Is there a way to reload the services without wiping out the auth tokens? Or maybe a way to always reload the services when in development?

Hello Scott.

On your site, do you have a JWT_SECRET set in your .env, and if so, is there a value set? If not, its probably generating a new random secret each time. Setting a value should persist them.

If you check the cbSecurity secret key, you should see something like this:

secretKey : getSystemSetting( “JWT_SECRET”, “” )

Setting a value in the env should fix it. I typically just generate a UUID, and then use that. Make sure you restart the site and reload the shell to confirm CommandBox sees the updated value. Thanks.

-Daniel GarcĂ­a

Scott,

I may have misread your post. Where are you storing the JWT tokens? If in a database, and you have set a secret, they should persist. If you are storing them in memory, like the cache, I believe that gets cleared on a reinit.

-Daniel Garcia

JWT persistence can be a bit tricky with local development because Coldbox clears its caches on reinit. Your best bet is to either store the tokens in the database using your storage settings or create a Lucee cache and then point the cachebox cache at that using the LuceeColdboxProvider.

Thanks for the quick replies. Maybe I need to rethink my approach.

Is there a way to force ColdBox to reload dependencies on each request?

I’ve used a similar setting in FW\1 apps in the past.

Depends on what you mean by dependencies :slight_smile:

A fwreinit nukes everything in memory, settings, objects, tokens, etc. So if you want your JWT tokens to persist across reinits, you need to store them outside of memory and make sure your JWT_SECRET is not regenerated. If you have it blank in your cbsecurity settings, then ColdBox will generate a secret upon startup.

I mean files like services. Is there a way to tell ColdBox to reload those on every request - in my case, in the development environment?

See if SingletonReload does what you need.

@bdw429s I’d advise against that, see issue here:

Having to now do a fwreinit after EVERY change in a singelton has become a huge PITA, I wish there was a workaround for dev?

I actually think that was a bug on our part @Andrew_Kretzer . Not sure if it was resolved in 7.2.

Also, you know you can do this yourself right?

Just listen to onRequestCapture in an interceptors, and wipe out whatever you want. So if there is something you want to clear, just listen and do what you want there.

@lmajano I’m not sure I understand? How would I do that with onRequestCapture?

As far as I can tell, the only way to “wipe out whatever I want” is to clear the entire singleton cache, like what’s done with the SingletonReload feature - but that also blows out framework singeltons which wreaks havoc as noted in that post.

What would be nice is if the SingletonReload feature could ignore singletons created by the framework. Or have Wirebox ignore the singleton annotations in dev in the first place.

Ok, I have added an update on be so the clearing of singletons only affects the app and not the core internals. This should help in this.

However, please note that if you create an onRequestCapture interceptor, you can clear ANYTHING you want from ANYWHERE. Interceptors are one of the most powerful features of ColdBox.

1 Like

@lmajano thank you, I will try this out on be!

I’m still interested in understanding your onRequestCapture remark?

I use interceptors extensively, so I understand that - in fact, I have so many that I had to write an admin module that allows me to rearrange both their order and their respective interception points order!

My difficulty is understanding what I would put into that interceptor to fix this issue?

E.g. if I have dozens of singleton objects that I am working on and I want to test changes I am incrementally making on all of them in dev, what code would I setup to fire onRequestCapture to grab fresh copies rather than the cached instances?

That was it.

Working nicely.

Thanks!

You’d get the singleton scope from WireBox and clear the entries you wanted fresh copies of. They’d be re-created the next time they were requested. I believe the singleton scope has a clear() method or you could loop over and clear them one by one based on your own logic.

@bdw429s right, so that’s what I thought. Unfortunately, that is not really a reasonable solution to the concern of having to reinit the framework after every change to a model. We’d have to write logic, in every Coldbox appication, to track a list of all models and then clear them one by one in onRequestCapture just for dev convenience.

The solution to separate fw from application singletons, which Luis recently added to the be Coldbox, seems to be the more elegant - and proper - approach. Coldbox already provides for this need with the SingletonReload flag, it’s just that CB-7 broke it, so it’s good to have it back!

I mean, it’s not nearly as complicated as I think you’re making it. ColdBox still stores all singletons together, the new method that only clears app singletons is right here:

which just removes all items not matching this short list:

Simple, indeed… if you have a firm grasp of the underpinnings of the fw and know what keys need to be excluded. I’m grateful for the fix.