Multiple step custom function authentication (magic link)


I want to implement a passwordless authentication method (magic link). Therefore, I have to implement two steps for the authentication:

  1. Send magic link including a token to the user email address
  2. Authenticate user with the given token + email address

My plan is to implement one function for each step. The first function is exposed using an HTTPS endpoint (system authentication as the user is not yet logged in), the second is triggered with the swift-sdk custom function authentication credential method.

My question is, first, is there a better way to implement this authentication? Second, how would I secure the HTTPS endpoint against e.g. DDoS attacks? I read in the docs that one can secure the endpoint with a secret, but is it best practice to store a secret somewhere in my project (e.g. info.plst)?

Thanks for the help

Can you elaborate a bit on what the tie-in is between this question and MongoDB Realm? Are you using Realm Authentication or some other technology?

When you say the first function is exposed using an HTTPS endpoint , what endpoint? Is this a web based or device based app?

Yes sure. I am using MongoDB Realm as my database service with sync enabled and Realm Authentication for authenticating my users. Currently, I have Apple Sign In + Email/Password authentication enabled, but I want to change the latter to a passwordless method using magic links.

Currently, I have the passwordless authentication running as an app service function which is tied to the custom function authentication method. Within the app I first call the login method of the realm sdk with the custom function credentials sending the email address as payload. The function then sends an email with a magic link to the user’s email address but fails because no token is send in the payload (on purpose). When the user clicks on the magic link, the login method is again called with the custom function credential, sending the email and token as payload. This time, if the token is correct (checked against a custom user collection), the user id is returned and the user is logged in. I do not use any third party service for the magic link authentication (all custom implemented in the app service function)

I guess it is not intended to call the login method twice and catch the error the first time (when the magic link is sent). Therefore my question whether the intended way for a multiple step custom function is to separate the app service function into two functions and expose the first function to send the magic link as an https endpoint (within app services). If so, how would one secure the endpoint, because it would need to be set to system authentication as the user is not logged in. I am not sure about storing a secret within the project.

Ok. So you’re using Realm Authentication with Custom Function User and the payload contains the users email address.

That email address is massaged externally and an email is sent. Can we assume the external service generates some kind of external user id after the user clicks the link in the email and returns it to the custom function?

Yes, correct.

Basically yes, but I am not using any external service for user authentication. I implemented everything myself within the custom function. Within that function I create an entry for the email address (if not already existing) in a custom mongodb user collection containing the email address, an “external” user id as well as a token. The token is send to the email address (using Sendgrid, which is only used for sending an email containing the magic link which I generated).

The part I don’t get is how to move forward. Currently I just call the login method in the swift sdk twice to handle the initial login (only email address as payload), which triggers sending the email containing the magic link, and the second time when the user clicks the link and then contains the email address + token as payload in which case the custom function returns the “external” user id.

You said the “external service” should return an external user id to the custom function. Is the custom function in this case waiting for the external service (until the user clicks the magic link)? If yes, how would you implement such a logic within mongodb only, meaning without external service (using app service functions + custom user collection).