Method for logged in users AND server-to-server


#1

Hi all,

I’m following @SkinnyGeek1010 's pattern by avoiding insert/allows and doing everything in methods. I have a method for an update that can happen from 2 actions: one is client-side (the user clicks on a button) but the other is server-side (another server is calling an API endpoint).
In the second case I don’t have a a userId. How can I allow both while preventing unlogged users from calling the method? Is there a pattern for this?

Thanks,
Tamás


#2

You probably want to use setUserId


#3

As @robfallows mentioned you might be able to use setUserId. I’m not sure in what cases this will/will-not work on.

Another issue you’ll run into if you have multiple DDP servers with multiple frontends is that calling the method from one client won’t work because this.userId is undefined.

For example, you have alpha.example.com and bravo.example.com and both have different front-end website. Both have signup/logins that can use the same user/password to sign in.

However, if your models are on alpha.example.com and your user is on bravo.example.com and logs in, they’ll have Meteor.user() defined but when they call the model on alpha, it will fail because this.userId is undefined.

To solve this I skipped using the this.userId check and had the method caller pass in the loginToken from local storage. Then each method can authenticate by querying the user by the token passed in. This lets you determine the userId of the caller yourself, regardless of what app is calling.

This also solves your case where a server is calling because you can query the user to get the token and then call, passing in the token.


However, if you just need to solve the server to server issue an easier solution is to use a secret key that is shared with all the production apps (a really long key so that it cant be brute forced). This key can optionally be passed into the method as the last argument (by convention) and if it exists and is valid than you don't have to check for the `this.userId`.

It’s unfortunate that Meteor makes it unnecessarily difficult to do microservices between client/server.


#4

Great points by @SkinnyGeek1010 :smile:


#5

I was thinking about this just yesterday.
How you track various action metrics? For me using methods instead of functions server-side looks like good way so we can see them in kadira.
But it is kinda hard to auth server to server, at least there is no default way how to do it.

So you are also trying to figure out best pattern seems.
Most of these will be server side called between microservices, or even 1 package calling method from same/other package. Never available for user due to private network, but still it feels kinda insecure.


#6

It’s not even a DDP connection, just a server-only function (mailgun incoming email parser) calling a client-and-server method (to insert the parsed message into a collection).

Right now I’m doing this (in the normal method):

if (!this.userId && this.connection !== null) { /* throw error */ }

But I’m not sure if its the best pattern for this.