Client Magic Link Workflow

magiclinksdev is an authentication project. It is essential to perform the correct steps in the correct order for authentication to be secure. This page describes the suggested authentication workflow for magic links.

Definitions

  • Server - The instance of the magiclinksdev being used.
  • Service account - An account on the server with programmatic access to the server's API.
  • Client application - The application using magiclinksdev for authentication. It has a service account.
  • User - A person using the client application.

Workflow

  1. Client application requests a magic link
  2. User clicks the magic link
  3. Client application accepts redirect
  4. Client application validates the JWT
  5. Client application treats the user as authenticated

A user initiated action causes the client application to request a magic link from the server. Currently, there are two types of magic link requests. See 1A and 1B.

1A: Email directly to the user

The client application makes a magic link email create request. This involves specifying the values for creating the magic link, JWT, and email template.

Upon processing the magic link email create request, the server will send the magic link directly to the user via email.

It is recommended that the client application add UI text to remind the user to check their email for the magic link.

The magic link and magic link secret will be sent to the client application in the response. These values can be safely ignored. Only use them if the user should be sent the same magic link via a custom alternative secure channel. Never present the magic link or its secret to an unauthenticated user.

1B: Custom delivery

The client application makes a magic link create request. This involves specifying the values for creating the magic link and JWT.

After the request is processed and the response is received, the client application is responsible for sending the magic link to the user through a custom secure channel. An example would be a mobile push notification.

To prevent confusion, it may be best to add UI text to inform the user of the following:

  • The user should check the platform where the magic link was sent.
  • Magic links can only be used once.
  • Magic links expire after a specified time.
  • Magic links should not be shared with anyone.

If the server is the magiclinksdev SaaS platform or otherwise configured to prevent robots using reCAPTCHA, add the reCAPTCHA branding visibly in the user flow. See this reCAPTCHA FAQ.


When a user clicks a magic link, they are directed to the server. The server will check the secret in the magic link, then craft and sign the JWT the magic link was configured for. The server will automatically redirect the user to the client application with the signed JWT in a URL query parameter.


Step 3: Client application accepts redirect

The client application must be listening via HTTP(S) at the redirect URL provided when the user clicks the magic link.

When a request is received, the user's JWT should be extracted from a URL query parameter. The default URL query parameter is jwt.


Step 4: Client application validates the JWT

The client application must validate the JWT properly. This is a crucial step where special attention is required. There are two documented methods to validate the user's JWT. See 4A and 4B.

4A: Validate the JWT using the JWT validation endpoint

The client application makes a jwt validate request. This involves passing the JWT from the URL query parameter to the server.

The server will verify the JWT signature, alg header, and registered claims. It will extract the claims as a JSON object and return them in the response back to the client application.

If the HTTP status code from the server is 200 OK, then the client application should treat the user as authenticated. Any other HTTP status code should fail authentication.

Method 4A is not network efficient. However, it may be best for use cases where the client application does not have an adequate JWK/JWT library. It also helps shorten development time.

4B: Validate the JWT locally using the JWK Set

The server publishes a JWK Set at /api/v2/jwks.json by default. This is a set of public keys that are used to verify JWT signatures. It would be ideal to cache this JWK Set and refresh the cache once an hour. It is essential that the JWK Set is downloaded using HTTPS.

The client application should cryptographically verify the JWT signature, alg header, and registered claims. Note that the server forces the sub claim to be empty.


Step 5: Client application treats the user as authenticated

After the client application has validated the user's JWT, it should treat the user as authenticated. This means the user should have access to the resources they are authorized to.

For web apps, see JWT browser cookie recommendations on the implementation tips page.