<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="272859" data-post-id="272859">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="type1fool" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/type1fool/120/26216_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  type1fool
                      <span class="op-star" title="Thread Starter">
                        <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                      </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<h2><a name="p-272859-update-sparkles-1" class="anchor" href="#p-272859-update-sparkles-1" aria-label="Heading link" rel="nofollow"></a>Update <img src="https://forum.elixirforum.com/images/emoji/apple/sparkles.png?v=15" title=":sparkles:" class="emoji" alt=":sparkles:" loading="lazy" width="20" height="20"></h2>
<blockquote>
<p>Still alpha after all these years</p>
</blockquote>
<p>I have updated <code>WebAuthnLiveComponent</code> with a new version which adds preliminary support for Passkeys. More specifically, <a href="https://developers.yubico.com/WebAuthn/WebAuthn_Developer_Guide/Resident_Keys.html" rel="noopener nofollow ugc">discoverable credentials</a> aka resident keys.</p>
<ul>
<li><a href="https://hexdocs.pm/webauthn_live_component/0.2.0/WebAuthnLiveComponent.PasskeyComponent.html" rel="noopener nofollow ugc"><code>WebAuthnLiveComponent.PasskeyComponent</code></a> is the module containing the new LiveComponent, which provides a drop-in pair of buttons for registration and authentication via Passkey in a LiveView application</li>
<li><code>passkey.js</code> contains the client-side Javascript for interacting with the WebAuthn API, sending events back to the <code>PasskeyComponent</code>, which in turn sends messages to the parent LiveView (see <a href="https://hexdocs.pm/webauthn_live_component/0.2.0/WebAuthnLiveComponent.PasskeyComponent.html#module-communication" rel="noopener nofollow ugc">Communication</a>).</li>
</ul>
<p>Thanks to <a class="mention" href="/u/dbern" rel="nofollow">@dbern</a> for moral support and asking great questions as I wrestled with implementing Passkey support. The mental model here is quite different from traditional authentication, so it was helpful to have someone to ask “how,” “why,” and “what if” throughout the process.</p>
<h2><a name="p-272859-whats-next-building_construction-2" class="anchor" href="#p-272859-whats-next-building_construction-2" aria-label="Heading link" rel="nofollow"></a>What’s Next? <img src="https://forum.elixirforum.com/images/emoji/apple/building_construction.png?v=15" title=":building_construction:" class="emoji" alt=":building_construction:" loading="lazy" width="20" height="20"></h2>
<p><strong>Split, merge, or ???</strong></p>
<p>The full module name, <code>WebAuthnLiveComponent.PasskeyComponent</code> is just a bit too much for my taste. I expect confusion about the two LiveComponents in this package, which are based on the same WebAuthn API, but take two approaches to implementation. The original component includes a form which requires a username before proceeding with registration or authentication.</p>
<p>So, I am <strong>looking for feedback</strong> on whether to split <code>PasskeyComponent</code> into its own Hex package, replace the WebAuthnLiveComponent module with the Passkey implementation, or something else. I am inclined to keep the original component for applications which would like to require a username first, though I would plan on replacing the form with a slot and using a <code>@changeset</code> assign to allow more control from the parent LiveView.</p>
<p>This is still an early alpha package with little adoption, but some excitement and interest expressed in this forum. So, there is still time to make significant changes to improve developer experience.</p>
<h2><a name="p-272859-speaking-of-developer-experience-construction_worker_woman-3" class="anchor" href="#p-272859-speaking-of-developer-experience-construction_worker_woman-3" aria-label="Heading link" rel="nofollow"></a>Speaking of Developer Experience <img src="https://forum.elixirforum.com/images/emoji/apple/construction_worker_woman.png?v=15" title=":construction_worker_woman:" class="emoji" alt=":construction_worker_woman:" loading="lazy" width="20" height="20"></h2>
<p>I spent some time documenting the <code>PasskeyComponent</code> module, but there is still more work required to clearly  document the process of using the component from start to finish. This includes adding the JS hook to the LiveSocket and several message handlers that must be added to the parent LiveView. Not to mention requirements for persisting the user’s public keys created during registration, as well as other requirements and best practices in the parent application.</p>
<h3><a name="p-272859-demo-application-4" class="anchor" href="#p-272859-demo-application-4" aria-label="Heading link" rel="nofollow"></a>Demo Application</h3>
<p>Updates to the demo Phoenix application are a <a href="https://github.com/liveshowy/webauthn_live_component_demo/compare/main...26-support-discoverable-creds" rel="noopener nofollow ugc">work in progress</a>. With the Hex package updated, some cleanup needs to be done to remove prototype component code. Other updates to the demo app include:</p>
<ul>
<li>Finish Live Session Hook implementation</li>
<li>Add <code>/passkey</code> link to landing page</li>
<li>Add tests for the <code>Passkey</code> LiveView</li>
<li>Remove <code>Auth</code> LiveView and route</li>
<li><code>...</code></li>
</ul>
<h2><a name="p-272859-contributions-handshake-5" class="anchor" href="#p-272859-contributions-handshake-5" aria-label="Heading link" rel="nofollow"></a>Contributions <img src="https://forum.elixirforum.com/images/emoji/apple/handshake.png?v=15" title=":handshake:" class="emoji" alt=":handshake:" loading="lazy" width="20" height="20"></h2>
<p>If you are interested in contributing, please don’t hesitate to respond in this thread. Since this is a potentially critical piece of security code, I believe it is important to keep the conversations as public as possible. <img src="https://forum.elixirforum.com/images/emoji/apple/pray.png?v=15" title=":pray:" class="emoji" alt=":pray:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="272859" data-batch-url="/posts/batch_likers">
                        7
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/webauthnlivecomponent-passwordless-auth-for-liveview-apps/49941/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-272859" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="272859"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #11"></div>
  </section>
</div>
    <div class="postbit" id="273012" data-post-id="273012">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="type1fool" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/type1fool/120/26216_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  type1fool
                      <span class="op-star" title="Thread Starter">
                        <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                      </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<h2><a name="p-273012-update-1" class="anchor" href="#p-273012-update-1" aria-label="Heading link" rel="nofollow"></a>Update</h2>
<blockquote>
<p>Getting beta all the time</p>
</blockquote>
<p>The <a href="https://github.com/liveshowy/webauthn_live_component_demo" rel="noopener nofollow ugc">demo application</a> has been updated with an implementation of the <code>PasskeyComponent</code>. The <a href="https://github.com/liveshowy/webauthn_live_component_demo/pull/6/files" rel="noopener nofollow ugc">PR is hefty</a>, in part due to some Tailwind auto sorting, but the code demonstrates registration, authentication, database design, and token persistence in the client and server.</p>
<h3><a name="p-273012-whats-included-2" class="anchor" href="#p-273012-whats-included-2" aria-label="Heading link" rel="nofollow"></a>What’s Included</h3>
<ul>
<li><code>DemoWeb.Hooks.User</code> includes two hooks for a) populating the <code>@current_user</code> assign and b) requiring a <code>@current_user</code> assign. See the router for example usage.</li>
<li>There are 9 messages passed to the parent LiveView via <code>handle_info</code> as the component coordinates with the application.</li>
<li>Users are automatically redirected to the user profile view upon successful registration and authentication.</li>
<li>Errors are passed from the component to the parent LiveView for customization and presentation.</li>
<li>The following schemas were added or updated:
<ul>
<li><code>Demo.Accounts.User</code></li>
<li><code>Demo.Accounts.UserProfile</code></li>
<li><code>Demo.Authentication.UserKey</code></li>
<li><code>Demo.Authentication.UserToken</code></li>
</ul>
</li>
</ul>
<h3><a name="p-273012-database-design-3" class="anchor" href="#p-273012-database-design-3" aria-label="Heading link" rel="nofollow"></a>Database Design</h3>
<p>With this implementation of discoverable credentials, I opted to register users <strong>without username or email</strong>. These fields were moved into <code>Demo.Accounts.UserProfile</code>. As a result the <code>Demo.Accounts.User</code> schema is quite bare.</p>
<p>The only downside I see with this approach is that the username is not stored in the user’s Passkey, which instead stores the component’s <code>@app</code> assign. I will be looking into whether existing passkeys may be renamed through the application.</p>
<p></p><div class="lightbox-wrapper"><a class="lightbox" href="https://forum.elixirforum.com/uploads/default/original/3X/f/f/ff36909344a0882103ce128633c160aa6ba62271.jpeg" data-download-href="https://forum.elixirforum.com/uploads/default/ff36909344a0882103ce128633c160aa6ba62271" title="image" rel="nofollow"><img src="https://forum.elixirforum.com/uploads/default/original/3X/f/f/ff36909344a0882103ce128633c160aa6ba62271.jpeg" alt="image" data-base62-sha1="ApIESIy4m6aKBSa9uyPufeKwQEh" width="690" height="434" data-dominant-color="2B2C2F"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">image</span><span class="informations">1200×756 22.1 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div><p></p>
<h3><a name="p-273012-test-drive-4" class="anchor" href="#p-273012-test-drive-4" aria-label="Heading link" rel="nofollow"></a>Test Drive</h3>
<p>With the demo application and component package updated, I am ready for feedback. With the hardest problems seemingly solved, I plan on improving documentation in both repos.</p>
<p>If you have a few minutes to review the code, launch the demo app, or even attempt implementation in your own application, <strong>I would greatly appreciate your feedback</strong>.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="273012" data-batch-url="/posts/batch_likers">
                        6
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/webauthnlivecomponent-passwordless-auth-for-liveview-apps/49941/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-273012" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="273012"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #12"></div>
  </section>
</div>
    <div class="postbit" id="273016" data-post-id="273016">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="derpycoder" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/derpycoder/120/31388_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  derpycoder
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>It’s so beautiful.</p>
<p>Observations:</p>
<ol>
<li>When I tabbed into the email field in User Profile page, my cursor didn’t show up the first time. (I don’t know how the focus got messed up)</li>
<li>I wish the sign in button changed in the first page to sign out.</li>
<li>There’s a flicker, when signing out &amp; signing in.</li>
<li>The toast message that shows up after successful sign in disappears because of the flicker.</li>
<li>Also, instead of using UUID, can it use KSUID, or we can change it later. <img src="https://forum.elixirforum.com/images/emoji/apple/sweat_smile.png?v=15" title=":sweat_smile:" class="emoji" alt=":sweat_smile:" loading="lazy" width="20" height="20"></li>
</ol>
<hr>
<p>P.S. Can the demo contain the <code>phx.gen.auth</code>, because I want to make sense of how both of them can be used together.</p>
<aside class="quote quote-modified" data-post="15" data-topic="51625">
  <div class="title">
    <div class="quote-controls"></div>
    <img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/derpycoder/48/31388_2.png" class="avatar">
    <div class="quote-title__text-content">
      <a href="https://forum.elixirforum.com/t/phoenix-1-7-0-rc-0-is-out/51625/15" rel="nofollow">Phoenix 1.7.0-rc.0 is out!</a> <a class="badge-category__wrapper " href="/c/news/phoenix-news/52" rel="nofollow"><span data-category-id="52" style="--category-badge-color: #FF6A18; --category-badge-text-color: #FFFFFF; --parent-category-badge-color: #d2407f;" data-parent-category-id="158" data-drop-close="true" class="badge-category --style-square --has-parent" title="Phoenix News Section"><span class="badge-category__name">Phoenix News</span></span></a>
    </div>
  </div>
  <blockquote>
    Tailwind is awesome. I like it when things that belong together, stay together. Also naming is hard so glad Tailwind takes care of it. 
I just picked up the classes, without fumbling through css and I was able to change the styling of generated Auth UI. 
I wish the UI generated by auth had the styling by default, but I don’t know how tough it is for generators to modify existing phx.new generated apps. 
[after logged in] 

[after logging in] 

[before logging in] 

[sign up] 

P.S. Generated UI …
  </blockquote>
</aside>

<hr>
<p>P.P.S. This is awesome. More people should get in on this.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="273016" data-batch-url="/posts/batch_likers">
                        3
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/webauthnlivecomponent-passwordless-auth-for-liveview-apps/49941/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-273016" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="273016"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #13"></div>
  </section>
</div>
    <div class="postbit" id="273107" data-post-id="273107">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="type1fool" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/type1fool/120/26216_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  type1fool
                      <span class="op-star" title="Thread Starter">
                        <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                      </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Thank you, <a class="mention" href="/u/derpycoder" rel="nofollow">@derpycoder</a>. I’ve opened <a href="https://github.com/liveshowy/webauthn_live_component_demo/pull/8" rel="noopener nofollow ugc">PR 8</a> to address this feedback. I’ll leave the PR open until tomorrow evening to allow time to review if you’re interested.</p>
<ol>
<li>I added <code>autofocus</code> to the first field in the user profile view.<br>
a. The disappearing cursor may have been related to some issues with the user hook (<span class="hashtag-raw">#3</span> below).</li>
<li>The home page’s <code>Sign In</code> button is now <code>My Profile</code>, which links to <code>/user/profile</code>.</li>
<li>The user hook was updated to remove an unnecessary redirect and to clean up the code a bit.<br>
a. Did this reduce/eliminate page flicker?</li>
<li>Flashes have been removed for now, and I’m <a href="https://elixir-lang.slack.com/archives/CD594E0UU/p1672277438331379" rel="noopener nofollow ugc">trying to understand</a> if/how they can be persisted across redirects.</li>
<li>Thanks for introducing me to KSUIDs.<br>
a. UUIDs are supported out of the box by Phoenix and Postgres.<br>
b. The demo app is just that, a demo app. KSUIDs might be cool, but the purpose of the demo app is to illustrate how the passkey component can be implemented.</li>
</ol>
<p>I’ve heard your feedback about <code>phx.gen.auth</code>. For now, my focus is on getting the implementation right for fresh Phoenix apps. My thinking is that passkeys are a <em>replacement</em> for traditional auth, though it’s likely most production apps will want a fallback to basic auth when passkeys are not supported. I have to review the auth generators and think about how to support both modes of authentication.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="273107" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/webauthnlivecomponent-passwordless-auth-for-liveview-apps/49941/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-273107" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="273107"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #14"></div>
  </section>
</div>
    <div class="postbit" id="273116" data-post-id="273116">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="derpycoder" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/derpycoder/120/31388_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  derpycoder
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>That’s awesome. <img src="https://forum.elixirforum.com/images/emoji/apple/smiley.png?v=15" title=":smiley:" class="emoji" alt=":smiley:" loading="lazy" width="20" height="20"></p>
<hr>
<aside class="quote no-group" data-username="type1fool" data-post="15" data-topic="49941">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/type1fool/48/26216_2.png" class="avatar"> type1fool:</div>
<blockquote>
<p>The demo app is just that, a demo app.</p>
</blockquote>
</aside>
<p>Yup, I don’t want you to add everything under the sun. I was just unsure if it’s possible to add it later as well.</p>
<aside class="quote no-group" data-username="type1fool" data-post="15" data-topic="49941">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/type1fool/48/26216_2.png" class="avatar"> type1fool:</div>
<blockquote>
<p>My thinking is that passkeys are a <em>replacement</em> for traditional auth, though it’s likely most production apps will want a fallback to basic auth when passkeys are not supported.</p>
</blockquote>
</aside>
<p>Same here, I just want to have both: for fallback as well as present it as 2nd factor or 3rd and finally, I want to see how they play together.</p>
<hr>
<p>I have yet to receive a YubiKey, hope to try that with this component.</p>
<hr>
<p>I will find some time to go through the code today. <img src="https://forum.elixirforum.com/images/emoji/apple/upside_down_face.png?v=15" title=":upside_down_face:" class="emoji" alt=":upside_down_face:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="273116" data-batch-url="/posts/batch_likers">
                        3
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/webauthnlivecomponent-passwordless-auth-for-liveview-apps/49941/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-273116" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="273116"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #15"></div>
  </section>
</div>
    <div class="postbit" id="273606" data-post-id="273606">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="type1fool" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/type1fool/120/26216_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  type1fool
                      <span class="op-star" title="Thread Starter">
                        <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                      </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<h2><a name="p-273606-update-1" class="anchor" href="#p-273606-update-1" aria-label="Heading link" rel="nofollow"></a>Update</h2>
<p>Thank you to everyone who has tried the updated component - it’s great to see the interest. Although interest is fairly low, it’s early days, and I’m glad to have the flexibility to make significant changes discussed below.</p>
<p></p><div class="lightbox-wrapper"><a class="lightbox" href="https://forum.elixirforum.com/uploads/default/original/3X/c/b/cb4b40c39cf5382b2495a3a76ed627b656763786.jpeg" data-download-href="https://forum.elixirforum.com/uploads/default/cb4b40c39cf5382b2495a3a76ed627b656763786" title="image" rel="nofollow"><img src="https://forum.elixirforum.com/uploads/default/optimized/3X/c/b/cb4b40c39cf5382b2495a3a76ed627b656763786_2_690x397.jpeg" alt="image" data-base62-sha1="t0q9CSZjdgFo6pzFsy5Sn7Mhjoi" width="690" height="397" srcset="https://forum.elixirforum.com/uploads/default/optimized/3X/c/b/cb4b40c39cf5382b2495a3a76ed627b656763786_2_690x397.jpeg, https://forum.elixirforum.com/uploads/default/optimized/3X/c/b/cb4b40c39cf5382b2495a3a76ed627b656763786_2_1035x595.jpeg 1.5x, https://forum.elixirforum.com/uploads/default/original/3X/c/b/cb4b40c39cf5382b2495a3a76ed627b656763786.jpeg 2x" data-dominant-color="F9F8F9"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">image</span><span class="informations">1200×692 38.5 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div><p></p>
<p>My next updates will add telemetry and improve documentation for this somewhat convoluted authentication process. The <a href="https://github.com/orgs/liveshowy/projects/3/views/1" rel="noopener nofollow ugc">public project</a> shows completed and planned work for this repo.</p>
<h2><a name="p-273606-re-mfa-2" class="anchor" href="#p-273606-re-mfa-2" aria-label="Heading link" rel="nofollow"></a>RE: MFA</h2>
<aside class="quote no-group quote-modified" data-username="derpycoder" data-post="16" data-topic="49941">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/derpycoder/48/31388_2.png" class="avatar"> derpycoder:</div>
<blockquote>
<p>… I just want to have both: for fallback as well as present it as 2nd factor or 3rd and finally, I want to see how they play together.</p>
</blockquote>
</aside>
<p>This clarifies things a bit. Now I understand you are also looking for multi factor authentication (MFA) for apps using <code>phx.gen.auth</code> or other implementations of traditional authentication.</p>
<p>Passkeys should be considered a more secure <em>alternative</em> to traditional authentication:</p>
<blockquote>
<p>Based on industry standards for account authentication, passkeys are easier to use than passwords and far more secure. Adopt passkeys to give people a simple, secure way to sign in to your apps and websites across platforms — with no passwords required.</p>
<p><a href="https://developer.apple.com/passkeys/" class="inline-onebox" rel="noopener nofollow ugc">Passkeys Overview - Apple Developer</a></p>
</blockquote>
<p>Once I am updating documentation, I will attempt to clearly distinguish between Passkeys and MFA.</p>
<p>For basic auth + MFA, WebAuthn <em>does</em> provide a better means of securing accounts than SMS, email, or one time password codes. However, I believe this would require a separate component since the flows are a bit different.</p>
<h3><a name="p-273606-multiple-keys-3" class="anchor" href="#p-273606-multiple-keys-3" aria-label="Heading link" rel="nofollow"></a>Multiple Keys</h3>
<p>Your question is in line with thoughts I was having towards the end of the demo app update:</p>
<blockquote>
<p>What if a user wants to add a secondary/backup/family/survivor key?</p>
</blockquote>
<p>The answer seems to be splitting up the <strong>registration</strong> and <strong>authentication</strong> buttons into separate components. By doing so, it may be easier to support MFA for apps using traditional auth:</p>
<ul>
<li>The registration component would need to accept user data.</li>
<li>It’s not clear yet whether the dedicated authentication component would also work well for MFA, or whether a separate component would be necessary.</li>
</ul>
<h2><a name="p-273606-hello-again-world-4" class="anchor" href="#p-273606-hello-again-world-4" aria-label="Heading link" rel="nofollow"></a>Hello Again, World!</h2>
<p>With this shift in component design, the time has come to retire the <code>webauthn_live_component</code> package and introduce <code>webauthn_components</code>. My hope is that this new package would be more flexible to the implementations we’ve discussed, possibly others.</p>
<ul>
<li><a href="https://hex.pm/packages/webauthn_components/0.2.2" rel="nofollow">webauthn_components on hex.pm</a></li>
<li><a href="https://github.com/liveshowy/webauthn_components" rel="noopener nofollow ugc">webauthn_components on github.com</a></li>
</ul> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="273606" data-batch-url="/posts/batch_likers">
                        5
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/webauthnlivecomponent-passwordless-auth-for-liveview-apps/49941/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-273606" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="273606"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #16"></div>
  </section>
</div>
    <div class="postbit" id="273840" data-post-id="273840">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="type1fool" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/type1fool/120/26216_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  type1fool
                      <span class="op-star" title="Thread Starter">
                        <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                      </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<h2><a name="p-273840-update-1" class="anchor" href="#p-273840-update-1" aria-label="Heading link" rel="nofollow"></a>Update</h2>
<p>I have opened <a href="https://github.com/liveshowy/webauthn_components/pull/37" rel="noopener nofollow ugc">PR 37</a> with the primary goals of <strong>breaking apart the components</strong> and <strong>improving documentation.</strong></p>
<p>This seemed more daunting than it turned out to be. I’m finding the separated components easier to understand and document, and I hope you agree.</p>
<ul>
<li>The README now includes <a href="https://github.com/liveshowy/webauthn_components/tree/34-split-registration-and-authentication#webauthn-flows" rel="noopener nofollow ugc">Mermaid diagrams</a> illustrating how each component interacts with the client and parent LiveView.</li>
<li>Each component has more complete module documentation with standardized sections for assigns, events, and messages.</li>
<li>A new <a href="https://github.com/liveshowy/webauthn_components/blob/34-split-registration-and-authentication/USAGE.md" rel="noopener nofollow ugc">USAGE.md</a> was added, and I plan on filling in more detail before closing the PR.</li>
</ul>
<p>Feedback is welcome, so feel free to review the code and documentation to check for errors and clarity. I request that questions and comments for the PR be added <strong>to the PR</strong> instead of the forum for posterity.</p>
<h2><a name="p-273840-whats-next-2" class="anchor" href="#p-273840-whats-next-2" aria-label="Heading link" rel="nofollow"></a>What’s Next</h2>
<p>You may notice that I’ve upgraded this repo from <strong>early alpha</strong> to <strong>early beta</strong> in the readme. The new design and documentation are key <img src="https://forum.elixirforum.com/images/emoji/apple/smirk.png?v=15" title=":smirk:" class="emoji" alt=":smirk:" loading="lazy" width="20" height="20"> to maintainability and adoption. Testing is also critical for a set of security-oriented components, and the modular design should make testing more straightforward than it would have been.</p>
<p>After this PR is merged, I plan to proceed with writing tests for each component. Last time I attempted to write tests, I discovered that there was little or no tooling for testing JS hooks. I believe the components may be tested using factories for users, user keys, and user tokens, but I’m not sure how to proceed with JS testing.</p>
<p>If you are interested in contributing to component and/or JS tests, let me know here or via DM so we can discuss. <img src="https://forum.elixirforum.com/images/emoji/apple/pray.png?v=15" title=":pray:" class="emoji" alt=":pray:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="273840" data-batch-url="/posts/batch_likers">
                        5
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/webauthnlivecomponent-passwordless-auth-for-liveview-apps/49941/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-273840" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="273840"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #17"></div>
  </section>
</div>
    <div class="postbit" id="275698" data-post-id="275698">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="type1fool" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/type1fool/120/26216_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  type1fool
                      <span class="op-star" title="Thread Starter">
                        <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                      </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<h2><a name="p-275698-update-v031-released-1" class="anchor" href="#p-275698-update-v031-released-1" aria-label="Heading link" rel="nofollow"></a>Update: v0.3.1 Released</h2>
<p><a href="https://github.com/liveshowy/webauthn_components/pull/37" rel="noopener nofollow ugc">PR 37</a> has been closed, with a major overhaul of the components. Here are the headlines:</p>
<ul>
<li>Components have been split up for better modularity</li>
<li>The package has been renamed to <code>WebauthnComponents</code> / <code>webauthn_components</code></li>
<li>Mermaid diagrams were added to the readme</li>
<li>Preliminary tests were added</li>
</ul>
<p>Separately, a <a href="https://github.com/liveshowy/webauthn_components_demo/compare/main...34-split-components" rel="noopener nofollow ugc">branch</a> is open for the demo repo, which has been renamed to <code>webauthn_components_demo</code> to factor in changes from the Hex package.</p>
<h2><a name="p-275698-links-2" class="anchor" href="#p-275698-links-2" aria-label="Heading link" rel="nofollow"></a>Links</h2>
<ul>
<li><a href="https://hexdocs.pm/webauthn_components/readme.html" rel="noopener nofollow ugc">HexDocs: webauthn_components</a></li>
<li><a href="https://github.com/liveshowy/webauthn_components" rel="noopener nofollow ugc">GitHub: webauthn_components</a></li>
<li><a href="https://github.com/liveshowy/webauthn_components_demo/compare/main...34-split-components" rel="noopener nofollow ugc">Example implementation (WIP)</a></li>
</ul> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="275698" data-batch-url="/posts/batch_likers">
                        4
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/webauthnlivecomponent-passwordless-auth-for-liveview-apps/49941/19">Post #18</a>
	                </div>
	            </div>
              <div id="likers-container-275698" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="275698"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #18"></div>
  </section>
</div>
    <div class="postbit" id="276100" data-post-id="276100">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="type1fool" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/type1fool/120/26216_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  type1fool
                      <span class="op-star" title="Thread Starter">
                        <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                      </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<h2><a name="p-276100-update-1" class="anchor" href="#p-276100-update-1" aria-label="Heading link" rel="nofollow"></a>Update</h2>
<p>The <a href="https://github.com/liveshowy/webauthn_components_demo" rel="noopener nofollow ugc"><code>webauthn_components_demo</code></a> repo has been updated with the new component implementation and a few developer experience improvements.</p>
<ol>
<li>Updated component implementation (<a href="https://github.com/liveshowy/webauthn_components_demo/pull/9" rel="noopener nofollow ugc">PR</a>)</li>
<li>Added Docker development container (<a href="https://github.com/liveshowy/webauthn_components_demo/tree/main/.devcontainer" rel="noopener nofollow ugc">code</a>)</li>
<li>Update the readme (<a href="https://github.com/liveshowy/webauthn_components_demo/blob/main/README.md" rel="noopener nofollow ugc">file</a>)</li>
</ol>
<p>With the new development container, it should be easier to get up and running since a Postgres container is included. The readme provides instructions for starting the app with or without a dev container.</p>
<h2><a name="p-276100-whats-next-2" class="anchor" href="#p-276100-whats-next-2" aria-label="Heading link" rel="nofollow"></a>What’s Next</h2>
<p>Because Passkey authentication is a big departure from traditional auth, I am planning to record a brief video demonstrating user flows and database storage. This should make adoption less daunting.</p>
<p>The remaining todos for this project are mostly related to developer experience. First, I plan to implement Telemetry in the components package so parent applications can attach to relevant events. Then, I want to investigate creating generators for some of the tedious code required to fully implement Passkey support in a Phoenix application.</p>
<h2><a name="p-276100-getting-involved-3" class="anchor" href="#p-276100-getting-involved-3" aria-label="Heading link" rel="nofollow"></a>Getting Involved</h2>
<p>In the meantime, I hope to start getting feedback from LiveView developers to refine the components and demo app, with the goal of building confidence for a 1.0 release.</p>
<p>Feel free to try out the demo app, provide feedback here, and share with anyone who may be interested in this project. <img src="https://forum.elixirforum.com/images/emoji/apple/pray.png?v=15" title=":pray:" class="emoji" alt=":pray:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="276100" data-batch-url="/posts/batch_likers">
                        6
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/webauthnlivecomponent-passwordless-auth-for-liveview-apps/49941/20">Post #19</a>
	                </div>
	            </div>
              <div id="likers-container-276100" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="276100"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #19"></div>
  </section>
</div>
    <div class="postbit" id="277759" data-post-id="277759">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="mward-sudo" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/mward-sudo/120/26932_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  mward-sudo
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Thanks for the work. I’m excited to start experimenting with webauthn.</p>
<p>In my trials I have an issue.</p>
<p>Registration and login works fine.</p>
<p>My home page and chat pages require login. I have the following in my <code>router.ex</code>, based on your demo repo:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">live_session :default, on_mount: {ChatWeb.Hooks.User, :assign_user} do
    scope "/", ChatWeb do
      pipe_through(:browser)

      live "/sign-in", Live.SignIn
      live "/sign-out", Live.SignOut, :sign_out
    end
  end

  live_session :authenticated,
    on_mount: [{ChatWeb.Hooks.User, :assign_user}, {ChatWeb.Hooks.User, :require_user}] do
    scope "/", ChatWeb do
      pipe_through(:browser)

      live("/", HomeLive, :home)
      live("/topic/:topic_name", TopicLive, :topic)
    end

    scope "/user", ChatWeb do
      pipe_through :browser

      live "/profile", Live.UserProfile
    end
</code></pre>
<p>Everything works fine - registration, login, etc.</p>
<p>However, <code>HomeLive</code> and <code>TopicLive</code> both require user info to be present. They work after logging in or registering while navigating the app. However, if I refresh the page on either then they error out with current_user being nil in the socket.</p>
<p>I have worked around the problem by having, on both:</p>
<ol>
<li>a <code>mount</code> function that pattern matches for the existence of <code>current_user</code> e.g. <code>%{assigns: %{current_user: %User{} = current_user}} = socket</code>)</li>
<li>a fallback mount function that  returns <code>{:ok, socket}</code> and doesn’t do any assigns</li>
<li>A <code>render</code> function that pattern matches for <code>username</code>, e.g. <code>%{username: _} = assigns</code></li>
<li>A fallback <code>render</code> function that renders a blank page.</li>
</ol>
<p>With these in place, things work. I believe there is a blank render with no user info, then another render with the user info.</p>
<p>Is this expected behaviour, or am I doing something incorrect?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="277759" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/webauthnlivecomponent-passwordless-auth-for-liveview-apps/49941/21">Post #20</a>
	                </div>
	            </div>
              <div id="likers-container-277759" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="277759"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #20"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <a class="load-more-button" data-turbo-stream="true" href="/topics/49941/load_more?page=3">Load more posts</a>
</div></template></turbo-stream>