JSVM global state

When writing middleware via the JVSM is there any access from a new TykJS.TykMiddleware.NewMiddleware({}); object to any shared state in memory (i.e. global vars)?

or could that really only be accomplished via using the TykGet/SetKeyData functions to read/write arbitrary keys to/from redis?

This Get/Set methods operate on Key session level, so not suitable for global vars.
We have ideas on adding Get/Set methods for custom data, in the next release.

Note that JSVM context is per API, so in theory you can define global JS variable, for temporary data, but it is not shared across multiple Gateway nodes.

BUT, Python middleware on the other hand have get_data and store_data methods, which do exactly what you want https://tyk.io/docs/customise-tyk/plugins/rich-plugins/python/tyk-python-api-methods/. It just sets and reads keys to Redis, just all created keys will have “coprocess-data:” prefix, to avoid any collisions.

ok, I asked, because this documentation is confusing, yes perhaps these methods should be renamed to specifically denote they are for session data only, vs just k/vs as the method name seems to imply: //tyk.io/docs/plugins/supported-languages/javascript-middleware/javascript-api/

it says

TykSetKeyData(api_key, api_id)

Yet the example sets a session OBJECT for the “api_id” parameter? Huh?

TykSetKeyData(event.EventMetaData.Key, JSON.stringify(thisSession));

Is there a doc describing what this “event.EventMetaData” object is and the spec of that Key value? Is that “key” the session identifier?

The doc is incorrect - the example is correct though.

Yup, events are discussed here, this is different from Middleware though

Thanks for the link, so if I were coding a plugin that was not a custom event handler, where would I get the correct value for the “key” parameter of TykSetKeyData and TykGetKeyData? “session.id”? or something?

It’s the key doing the accessing - you would need to extract this from the request (usually a header or a param), it isn’t passed to the function.

So if I’m using that “id_extractor” where the “key” for the session is the basic auth header’s hashed value… its unclear to me how I would get that value (the md5 hash) that whatever is invoking my function is creating on my behalf. I dumped the “request” object and don’t see any reference to a session key there. I would not expect that I have to have a contract w/ the http client invoking me to accept a cookie/header manage that value… i thought tyk would w/ the hash of the inbound auth header for the session key

I think there’s a misunderstanding here.

The ID extractor is there to prevent an additional round trip to the middleware - no more, so if you use it, your middleware won’t even be executed if the ID extractor finds the cached session object. Then when the cache expires, your code needs to supply a new one. It’a a speed boost, not state.

If you want to persist state (the session object) across requests then you need to store it yourself and manage that yourself, it’s a custom auth handler after all.

The GetKeyData/SetKeyData functions are for tokens that are managed and created by Tyk, not auth you are managing yourself. If you have middleware that tracks data for a user, or needs to add meta data to flag operations, or create new tokens in real time, or invalidate tokens based on behaviour (in a pre processor / pre-auth for example).

The ID extractor is there to prevent an additional round trip to the middleware - no more, so if you use it, your middleware won’t even be executed if the ID extractor finds the cached session object. Then when the cache expires, your code needs to supply a new one. It’a a speed boost, not state.

Perfect, thats what I want and that is my understanding. I’m just not seeing that work per my post @ NPM and JSVM, custom basic-auth plugin more details? - #19 by matiasb

If you want to persist state (the session object) across requests then you need to store it yourself and manage that yourself, it’s a custom auth handler after all.

Here is the confusion I guess. I want to do this, but you are saying the method above in fact does this, but yet here you say I need to do it myself? Confused.

In the example I was directed to for an JSVM “auth” plugin, the plugin returned a session object to the invoker of the function via returnAuthData. I was under the impression that doing this in combination with the “id_extractor” that a “session” would be established, keyed by the Authorization header and stored in redis. All subsequent invocations of the “auth” handler would be skipped until that session is expired.

I don’t have any need to track any meta-data particular to a user on the session. I just want to avoid repeated calls to my auth plugin which itself calls out to another service. One call per unique Authorization header, if it passes, estab this session keyed by the auth header, and don’t call my auth plugin again until that expires. Thats it.

Perhaps I need to do a call w/ you guys, as by reading the docs something is not clicking, some diagrams of the internal flow of tyk with regards to components that invoke w/ these plugins and the interaction w/ the thread might be helpful as the docs simply are not conveying this if I am mis-understanding it. We are evaluating this prior to purchase, had a call w/ James earlier in the week.

You’re correct here, and you just need to use the ID extractor, and make the TTL as long as your re-auth period.

The Tyk SessionObject can be used to store long-term state in the meta data fields, since Tyk will “expire” tokens, but the Session data persists (difference between not allowed/expired and not found/evicted). For example, if you generate a token in Tyk and then need to have a reference to the actual user ID of the user etc. This token has a lifetime of 1 week. After 1 week, you may want to extend the validity of the key (this happens more often than you think, for example when people bake a token into an application). So Tyk stores all this data long-term, and expiry is not the same as a cache eviction. So, in Tyk a SessionObject can track long-term state.

The ID extractor will not do this, it evidcts the cached entry, so any meta data or addiitonal information that is being tracked alongside this user is not persisted beyond the lifetime of the cached object. You need to do it yourself, in your case, the data is in ldap and managed elsewhere (so you do not need this at all), but in other cases where the request is validated with e.g. SAML or some other system, then you may want to persist long-term state in some way. In a custom auth plugin, you need to do this yourself.

When you asked about the GetKeyData and SetKeyData functions, that’s what they are for, they are there to either forward-populate a Tyk-managed SessionObject and Key (as in you can manage it via the dashboard), or to do token exchange (inbound token is x, generate token y, use token y for the remainder of the request through header substitution etc.)

The bottom line in: Just use the ID extractor, everything else is a distraction.

Thanks for the detail and help BTW!

You’re correct here, and you just need to use the ID extractor, and make the TTL as long as your re-auth period.

i.e. the TTL meaning, the “session_lifetime” attribute for the API def?

Per the rest of it, I think I get the scenario, and yes, I don’t really have that need at this point.

Yes, just set this value to what you want the cache to expire at in seconds.