p2-inc / keycloak-magic-link

Magic Link Authentication for Keycloak
https://phasetwo.io
Other
245 stars 50 forks source link

Native mobile app - possible approaches? #82

Closed alainkaiser closed 4 months ago

alainkaiser commented 4 months ago

Hei :)

First of all, thanks for the wonderful implementation. After some research and setup I got it working locally and also tested it via mailhog. Works pretty good in the web.

What I'm wondering now: We are planning to implement a native mobile app (App Store and Google Play Store). The current idea is that we want to build the login screens ourselves and use the Magic Link approach. The user would log in as follows:

For me it is quite clear that you could use something like deep links for the redirect to the app from the email. You could modify the email templates, for example.

However, I have no idea what should then happen or how I can get a token within the native app using the Magic Link.

Have you had any experience with this? Resp. is this approach even possible with this extension / plugin? I would be grateful for any feedback.

xgp commented 4 months ago

The magic link continuation implementation works kind of like what you want. The initial login page "polls" to see if the link has been clicked somwhere.

You could likely do a similar thing inside your application, but this implementation won't do it for you. If you figure it out and want to contribute it, please reopen this with your findings.

alainkaiser commented 4 months ago

@xgp Thanks for your response. I am just wondering:

If I don't wanna use the templates from keycloak and just implement the entire flow manually, where can I get an overview of the endpoints I can work with? I mean in the docs of this repo, I saw the /magic-link endpoint, but a lot of things are not clear for me.

Sample request (replace your access token):

curl --request POST https://keycloak.host/auth/realms/test/magic-link \
 --header "Accept: application/json" \
 --header "Content-Type: application/json" \
 --header "Authorization: Bearer <access_token>" \
 --data '{"email":"foo@foo.com","client_id":"account-console","redirect_uri":"https://keycloak.host/auth/realms/test/account/","expiration_seconds":3600,"force_create":true,"update_profile":true,"update_password":true,"send_email":false}'

Questions:

After, when I look at the sample response from the endpoint call above, it is something like that:

{
  "user_id": "386edecf-3e43-41fd-886c-c674eea41034",
  "link": "https://keycloak.host/auth/realms/test/login-actions/action-token?key=eyJhbG...KWuDyE&client_id=account-console",
  "sent": false
}

There is the actual magic link as a link. But how do I continue from there within the native app? I mean the link will be sent to the users email, he clicks on it and gets redirected to the native app via a deeplink or something like that. But what should happen next? Can I extract some infos from the magic link to hit the next endpoint?

I hope it is not too confusing...

xgp commented 4 months ago

That endpoint returns the link as well as optionally sends the link to the user's email. Once the user clicks on that link, they are authenticated, and redirected to the redirect_uri. The normal behavior is that the application at that redirect_uri does a normal code-to-token flow, which "just works" because the user is already SSO logged in.

But what should happen next?

No idea.

Can I extract some infos from the magic link to hit the next endpoint?

I don't think that would be helpful. There is not "endpoint" to "hit".

It's a neat use case, but really way out of scope of what this is designed to do. If you figure out a way to use some piece of what is here and care to share, please post your solution.

edwardmp commented 1 month ago

For who's interested, I managed to get this to work like @xgp describes. You could support magic link sign-in completely in native elements this way.

From your backend you can hit the https://keycloak.host/auth/realms/test/magic-link endpoint described above. Just make sure the redirect_uri is either a URI scheme registered to be handled by your app, or an equivalent universal link.

Then, when the user clicks the magic link in the email, use the default OS handlers to get the link that was pressed to open the app, and extract the "&code=" param in the url. Use that value for a normal authorization code-to-token flow and bob's your uncle:

curl -X "POST" "http://localhost:8090/realms/my-realmprotocol/openid-connect/token" \
     -H 'Content-Type: application/x-www-form-urlencoded' \
     --data-urlencode "grant_type=authorization_code" \
     --data-urlencode "code=b5c7a811-0e61-42b9-9fc5-934fd614b57e.ff2148c2-a20d-4efc-ba8e-e7825f5ae204.edd26036-7f7e-4a91-be47-84603e57e3aa" \
     --data-urlencode "client_id=account-console" \
     --data-urlencode "redirect_uri=myapp://redirect"
alainkaiser commented 1 month ago

@edwardmp Nice, thanks for your detailed inputs on this. Love it!