Magic Link login: Authenticator and Resource

Hi All,

I’ve open sourced an extension that I thought the community could use. I often see posts here asking about “Magic Link” login. I know there are a few sample and experimental implementations out there, and this is my addition.

This implementation differs from others in that it creates an ActionToken that is sent as the link. This is convenient, as it does not require the user to click on the link from the same device, nor for the same authentication session to be active when the user clicks on the link

In my extension, there are two ways to generate a Magic Link:

  1. An Authenticator that can run in your login flow. This has a form that takes an email, looks up the User by that email, and can optionally create a user if none exists. It sends the email using a theme-resources template, which you can override. Installation can be achieved by duplicating the Browser flow, and replacing the normal Username/Password/OTP forms with the Magic Link execution type.
  2. A Resource you can call with manage-users role, which allows you to specify the email, clientId, redirectUri, tokenExpiry and optionally if the email is sent, or the link is just returned to the caller. This is useful if you are building something that wants to deliver the Magic Link in another way, or simply wish to build the email in a way that Keycloak templating doesn’t support.

A variation of this code has been used in production for several months. I made a few changes in the process of preparing the code for open source, so please let me know if you find any problems.

Enjoy!

3 Likes

Hey there. This looks like a great implementation of this feature, but I’m having a problem with it. I seem to have everything set up as you describe, but I am getting a “401 unauthorized” error when I try to run the curl command. The only significant difference may be the version of keycloak we are running. I’m running 18 locally to test this, but you never mentioned the version you were running.

curl --location --request POST 'http://localhost:8080/realms/MagicLink_Test/magic-link' \
 --header 'Accept: application/json' \
 --header 'Content-Type: application/json' \
 --header 'Authorization: Bearer' \
 --data '{"email":"xxx@xxx.com","client_id":"magiclink-app","redirect_uri":"http://localhost:8080/realms/MagicLink-Test/account/","expiration_seconds":3600,"force_create":true,"update_profile":true,"send_email":false}'

{"error":"HTTP 401 Unauthorized"}%

Am I supposed to put something in that Bearer token spot? That would seem unintuitive given what we are trying to accomplish here, but maybe I’m missing something. Looking forward to hearing back! Thanks.

You must include an access token from a user with manage-users role.

Authorization: Bearer <access_token_goes_here>

That did it! Thank you, sir!

@xgp One more question. Do you think it would be possible for this magic link registration/login to take place with only a phone number rather than an email? Or would Keycloak’s internals prevent such a solution? Is my boss asking the impossible? (wouldn’t be the first time :wink: ). Thanks in advance!

This extension was not designed to be used with phone number. A few issues:

  1. you would have to extend Keycloak to create and lookup users based on phone number alone

  2. this extension uses an action token in the link url that would be longer than the maximum SMS length (usually 160 characters)

Gotcha. Thanks for the input!