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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>To be more explicit:</p>
<p>JWT is used for stateless service access.  Like it is a token that is valid for, say, 5 minutes to access an image on a remote object store service, generated so that the client itself can hold on to it and pass it along without those two servers ever needing to communicate.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="134549" 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/to-use-guardian-db-or-not/23617/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-134549" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="134549"
                     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="134592" data-post-id="134592">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<blockquote>
<p>No you do not need to keep track of it. If you keep track then you use stateful JWT, which removes all niceties of JWT.</p>
</blockquote>
<p>How do you reject a token without keeping track of it?</p>
<p>The original question was is this the only way to invalidate tokens. JWT are stateless. I thought the only solution to this is to keep track of the token to invalidate it.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="134592" data-batch-url="/posts/batch_likers">
                        0
                      </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/to-use-guardian-db-or-not/23617/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-134592" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="134592"
                     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="134658" data-post-id="134658">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="mythicalprogrammer" data-post="13" data-topic="23617">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/mythicalprogrammer/48/10430_2.png" class="avatar"> mythicalprogrammer:</div>
<blockquote>
<p>How do you reject a token without keeping track of it?</p>
</blockquote>
</aside>
<p>Just like in <a class="mention" href="/u/overminddl1" rel="nofollow">@OvermindDL1</a> example. If you use JWT as a “one time token” then you just make them expire fairly quickly.</p>
<p>JWT itself is not stateful or stateless, it all depend on the way you use them. And if you need to keep track of all invalidated tokens then you have stateful JWTs. That is simple as that.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="134658" data-batch-url="/posts/batch_likers">
                        0
                      </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/to-use-guardian-db-or-not/23617/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-134658" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="134658"
                     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="134949" data-post-id="134949">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<blockquote>
<p>Just like in <a class="mention" href="/u/overminddl1" rel="nofollow">@OvermindDL1</a> example. If you use JWT as a “one time token” then you just make them expire fairly quickly.</p>
</blockquote>
<p>I’m going to respectfully disagree with you that this type of action count as rejection or invalidating.</p>
<p><a href="https://elixirschool.com/en/lessons/libraries/guardian/#do-i-have-to-use-a-database" rel="noopener nofollow ugc">The guardian doc also imply using database for certain actions including this.</a></p>
<blockquote>
<p>JWT itself is not stateful or stateless, it all depend on the way you use them. And if you need to keep track of all invalidated tokens then you have stateful JWTs. That is simple as that.</p>
</blockquote>
<p>I’m also going to respectfully disagree with you on this. From my understand JWT are described as stateless because of how it is authenticated.</p>
<p><a href="https://forum.elixirforum.com/t/to-use-guardian-db-or-not/23617/14" rel="nofollow">At least under the wiki article this is how JWT are described as when using stateless.</a></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="134949" data-batch-url="/posts/batch_likers">
                        0
                      </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/to-use-guardian-db-or-not/23617/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-134949" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="134949"
                     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="134969" data-post-id="134969">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Morning!</p>
<p>I think what <a class="mention" href="/u/hauleth" rel="nofollow">@hauleth</a>&amp; co. mean that it becomes stateful if you save it to the database and then add like a “revoked” column or something because that adds “mutable” state to it instead of just handing it off and be done with it.</p>
<p>As for valid JWT use cases, here’s where we used it:</p>
<p></p><div class="lightbox-wrapper"><a class="lightbox" href="https://forum.elixirforum.com/uploads/default/original/3X/d/e/decae571eb9737c2bc79eff53495cb2acc645c5e.png" data-download-href="https://forum.elixirforum.com/uploads/default/decae571eb9737c2bc79eff53495cb2acc645c5e" title="image" rel="nofollow"><img src="https://forum.elixirforum.com/uploads/default/optimized/3X/d/e/decae571eb9737c2bc79eff53495cb2acc645c5e_2_690x436.png" alt="image" data-base62-sha1="vMUHviVMfDEn7l5YUozpE525HfU" width="690" height="436" srcset="https://forum.elixirforum.com/uploads/default/optimized/3X/d/e/decae571eb9737c2bc79eff53495cb2acc645c5e_2_690x436.png, https://forum.elixirforum.com/uploads/default/original/3X/d/e/decae571eb9737c2bc79eff53495cb2acc645c5e.png 1.5x, https://forum.elixirforum.com/uploads/default/original/3X/d/e/decae571eb9737c2bc79eff53495cb2acc645c5e.png 2x" data-dominant-color="E8D9DD"><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">973×616 37 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>Basically we had a separate (elixir) tracking service. That service needed to know whether you were allowed to push or read locations and for which courier_id. So the “main application” created JWTs encoding for which courier_ids you had what access rights. Both the web frontend and the courier app could then just present this token to the service and be done with it.<br>
There was no invalidation or something, we set the expiry to 30 minutes or something so then the client would have to request a new one. That was fine (imo) as the attack vector for pushing or reading locations for such a limited time isn’t that scary.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="134969" 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/to-use-guardian-db-or-not/23617/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-134969" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="134969"
                     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="135071" data-post-id="135071">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Disclaimer: I’m a maintainer of a JWT library <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p>
<p>The usefulness of JWTs and the stateful vs stateless approach is a somewhat heated debate on many communities… I think most of the time people are not comparing apples to apples.</p>
<p>When we say a JWT can be the same thing as a cookie there are many things that are not being taken into account IMHO. First of all, JWTs are one of many specifications in the JOSE umbrella (not José Valim, but JavaScript Object Signing and Encryption specifications). So, in reality it can be either a JWS (a signed token) or a JWE (an encrypted token).</p>
<p>Most of the time people who are for using cookies instead of JWTs are thinking only of signed tokens. More than that: people are thinking about tokens signed with symmetric encryption (a secret key that only the issuer of the token knows about it). This is not the best use case for JWTs and I agree with all the folks here about it. Cookies have better security if all you want is a session id (they can be set to be HTTPS only and with that no JS will reach it - in theory).</p>
<p>Where it shines, though, is when you have a setup with asymmetric encryption (public/private key pairs). I will not say this is more or less common. It seems most people here do their own authentication and are fine with it. In my experience, most corps rely on a centralized user storage with identity brokering, federation and what not… On this scenario you don’t have the user credentials and that is a good thing because your liability is different than when you have to store user credentials.</p>
<p>With asymmetric encryption (and signing) you can receive a token that <strong>you are not the issuer</strong> and still verify its authenticity by using the issuer’s public key which is, well, public. Many authentication schemes use this like OAuth2 with OpenID. <a href="https://www.googleapis.com/oauth2/v3/certs" rel="noopener nofollow ugc">Google</a>, <a href="https://login.microsoftonline.com/common/discovery/keys" rel="noopener nofollow ugc">Microsoft</a> and then some are using this scheme.</p>
<p>Another area where JWTs (and all the other JOSE specs) might be helpful is on standard encryption mechanisms and libraries. Cryptography is a tricky thing that most people don’t like to study ir. So, if you have to perform something like payload encryption, using JWEs might be a lot easier and safer than rolling your own encryption protocol (<em>do not do that please…</em>). One place where I’ve seen this being implemented is, for example, webhooks. You must ensure they are signed and encrypted to avoid tampering, miss authentication and so on. That is where most people get it wrong having to decide block ciphers, padding schemes, modes of operation and so on.</p>
<p>Well, you could simply turn your payload into a signed JWT (JWS) and then encrypt it with a public key of the receiver into another JWT (JWE). What is cool about this is that almost every language has a library for JWS and JWEs. It eases the “cryptography” burden for integration.</p>
<p>Of course you should still know what you are doing. These specifications have wrong interpretations, updates and so on. Signed JWTs, for example, used to pass which algorithm it used to sign it on the header. Some people simply passed the “none” algorithm and many libraries accepted that by default. This is just one example but there are others…</p>
<p>So, in conclusion, I see the JWT, JWS, JWE, JWA (JSON Web Algorithms), JWK (JSON Web Keys), JWKS (JSON Web Key Set) and extended specifications (like using Edwards Curve for signing/encryption) as a <strong>tool</strong> that can be used in many scenarios. The one of holding a “session” might be a good fit or not depending on your requirements.</p>
<p>For all that, I simply don’t agree with the sentence “JWTs are a solution looking for a problem”.</p>
<p>Anyway, I deviated too much from the discussion. Sorry for that!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="135071" data-batch-url="/posts/batch_likers">
                        10
                      </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/to-use-guardian-db-or-not/23617/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-135071" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="135071"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-last-post cat-last-post" title="Last post!"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <span class="all-loaded">— All posts loaded —</span>
</div></template></turbo-stream>