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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Hi, author of the “don’t use JWT for sessions” article here.</p>
<p>I would take any articles from Auth0 with a grain of salt - they appear to have some vested interest in recommending JWT, and seem to spend a <em>considerable</em> chunk of their blog posts on recommending it in various ways. JWT tokens are absolutely not more future-proof than sessions - they are a different solution for a different problem. Implementing a blacklist system isn’t really a good solution, either - I’ve covered that in <a href="http://cryto.net/~joepie91/blog/2016/06/19/stop-using-jwt-for-sessions-part-2-why-your-solution-doesnt-work/" rel="noopener nofollow ugc">my follow-up post</a>.</p>
<p>Similarly, storing it in Local Storage is just never okay, as it will open you up to session stealing. This is a problem that (HttpOnly) cookies do not have.</p>
<p>The summary is that there are no usecases where JWT are a good option <em>for sessions</em> - the only case in which it’s a valid choice is if you are scaling up so much that you just <em>can’t</em> have a centralized session store. It’s still not a <em>good</em> option, but stateless JWT (or similar stateless token schemes) are pretty much just the only option you have left.</p>
<p>EDIT: Of course, if there <em>are</em> no well-tested session implementations available for your stack, then a stateful JWT token can be a useful way to implement signed session IDs. But you’d still not store the actual session data <em>in</em> the token.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="5849" 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/guardian-jwt-vs-phoenix-token/853/32">Post #31</a>
	                </div>
	            </div>
              <div id="likers-container-5849" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="5849"
                     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 #31"></div>
  </section>
</div>
    <div class="postbit" id="6234" data-post-id="6234">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Thanks for posting, certainly some interesting reading material. Quck question: is storing sessions in any way on the client not a bad idea, and not JWT specific?</p>
<p>First I though that <em>sessions</em> were not needed when communicating with a JSON API from a mobile app. But after further thought, a authorized user can be considered a logged in user, and I guess this can be considered a session if you also want tog-out an user. It has a logged-in state.</p>
<p>So storing a <strong>signed session id</strong> in a token could be a way to go. On every request you would retrieve the user data linked to this session id from a fast database (for example Redis) and continue.I think this is already a widely used pattern.</p>
<p>Any Elixir specific implementations that would add value as an Redis alternative?</p>
<ul>
<li>GenServer;</li>
<li>ETS,</li>
<li>DETS,</li>
<li>Mnesia</li>
</ul>
<p>Thoughts?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="6234" 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/guardian-jwt-vs-phoenix-token/853/33">Post #32</a>
	                </div>
	            </div>
              <div id="likers-container-6234" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="6234"
                     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 #32"></div>
  </section>
</div>
    <div class="postbit" id="6243" data-post-id="6243">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>An older article discussing session storage in cookies that might be interesting:<br>
<a href="http://wonko.com/post/why-you-probably-shouldnt-use-cookies-to-store-session-data" rel="noopener nofollow ugc">Why you probably shouldn’t use cookies to store session data</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="6243" 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/guardian-jwt-vs-phoenix-token/853/34">Post #33</a>
	                </div>
	            </div>
              <div id="likers-container-6243" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="6243"
                     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 #33"></div>
  </section>
</div>
    <div class="postbit" id="6259" data-post-id="6259">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I would say that storing session <em>data</em> on the client side is always a bad idea, for the reasons already outlined in the article you referenced. That having been said, there are some edge cases where - despite it being a bad idea - it’s still the <em>least bad</em> idea; in particular, in highly scalable setups where centralized session storage is just somehow not viable.</p>
<p>Very few people run into those situations, though, so I’d strongly recommend against building something like that as a general-purpose solution, and would argue to leave it a specialized option instead.</p>
<p>Storing a signed session ID in the cookie, using centralized session data storage, is definitely the way to go for a generic implementation. Redis is a fairly widely used option, but not necessarily the only good one; any kind of store can work, really, and if you are already using a database (such as PostgreSQL), then it can be desirable to store sessions there as well - at least until scale demands otherwise. The less moving parts you can get away with, the better.</p>
<p>I wouldn’t have any Elixir-specific recommendations, personally; I haven’t actually used Elixir (yet), and I just ended up here after checking the referrers for my article. It’s a useful approach to addressing questions and misunderstandings across the web <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> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="6259" 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/guardian-jwt-vs-phoenix-token/853/35">Post #34</a>
	                </div>
	            </div>
              <div id="likers-container-6259" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="6259"
                     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 #34"></div>
  </section>
</div>
    <div class="postbit" id="6356" data-post-id="6356">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Interesting. It seems then that the cookie approach in Phoenix is not ideal either where user specific information is stored.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="6356" 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/guardian-jwt-vs-phoenix-token/853/36">Post #35</a>
	                </div>
	            </div>
              <div id="likers-container-6356" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="6356"
                     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 #35"></div>
  </section>
</div>
    <div class="postbit" id="6561" data-post-id="6561">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>So I’ve looked into it further and are still exploring the best options. I’ve looked into the <strong>signed session id</strong> approach.<br>
For my hobby project I’m working with a JSON API, and cookies are not really an options. Taking into account that a JWT signs it claims, isn’t this almost the same as a <strong>signed session id</strong>? Of course, now it’s up to the developer to store nothing else besides the sessionID.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="6561" 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/guardian-jwt-vs-phoenix-token/853/37">Post #36</a>
	                </div>
	            </div>
              <div id="likers-container-6561" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="6561"
                     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 #36"></div>
  </section>
</div>
    <div class="postbit" id="6622" data-post-id="6622">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>To invalidate JWTs, people use one of two methods</p>
<ul>
<li>a blacklist</li>
<li>a refresh token (which allows regenerating access tokens) with a short expiring access token.</li>
</ul>
<p>In a general way, there are pros and cons to pretty much every approach to authentication. JWTs make it easy to do some things (client side auth, SSO, serverless apps), and harder to do others, like invalidation. Would recommend reading the HN discussion ( <a href="https://news.ycombinator.com/item?id=11895440" class="inline-onebox" rel="noopener nofollow ugc">Don't use JSON web tokens for sessions | Hacker News</a>) around the critical article that was linked to in this this thread</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="6622" 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/guardian-jwt-vs-phoenix-token/853/38">Post #37</a>
	                </div>
	            </div>
              <div id="likers-container-6622" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="6622"
                     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 #37"></div>
  </section>
</div>
    <div class="postbit" id="6624" data-post-id="6624">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I dont think that link applies to JWTs for the following reasons</p>
<p>performance: JWTs are not for storing all session data, they are for authorizing a request, so they wont have the same size characteristics that signed cookies do. Also, JWTs can be sent as request headers. If you have a single page application, you can choose to not store them in the cookies.</p>
<p>security: i have yet to work on a web application that didnt have dozens of secrets that needed to be kept out of source control and managed on servers. Your JWT private key is just another one.</p>
<p>Would also point out that pretty much every major tech company uses bearer tokens (facebook, google, microsoft, etc) which are very similar in concept to JWTs. Not saying that automatically makes it a good idea for you and your app, but in a general way this is a well vetted idea.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="6624" 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/guardian-jwt-vs-phoenix-token/853/39">Post #38</a>
	                </div>
	            </div>
              <div id="likers-container-6624" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="6624"
                     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 #38"></div>
  </section>
</div>
    <div class="postbit" id="6628" data-post-id="6628">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>In my post i’m offering to <strong>only</strong> store a session ID, nothing more.</p>
<aside class="quote no-group" data-username="mbriggs" data-post="38" data-topic="853">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/mbriggs/48/1920_2.png" class="avatar"> mbriggs:</div>
<blockquote>
<p>To invalidate JWTs, people use one of two methods</p>
<p>a blacklist<br>
a refresh token (which allows regenerating access tokens) with a short expiring access token.</p>
</blockquote>
</aside>
<p>I have used both methods in the past and they do work (with their tradeoffs offcourse). But creates it’s own problems (as <a href="http://cryto.net/~joepie91/blog/2016/06/19/stop-using-jwt-for-sessions-part-2-why-your-solution-doesnt-work/" rel="noopener nofollow ugc">pointed out here</a>.</p>
<p>a blacklist → why dont store sessions serverside? Isn’t this alsmost the same,<br>
refresh tokens → what if you want to revoke this token for a specific user?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="6628" 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/guardian-jwt-vs-phoenix-token/853/40">Post #39</a>
	                </div>
	            </div>
              <div id="likers-container-6628" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="6628"
                     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 #39"></div>
  </section>
</div>
    <div class="postbit" id="6631" data-post-id="6631">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="benwilson512" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/benwilson512/120/1457_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  benwilson512
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Author of Craft GraphQL APIs in Elixir with Absinthe</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>A blacklist is by its very nature almost always a small subset of your total user base. Also, you only need to keep an item in the blacklist until the JWT key expires. Thus, the size of the blacklists is merely the number of users blacklisted in the last N minutes, which is usually a fraction of the total number of users.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="6631" 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/guardian-jwt-vs-phoenix-token/853/41">Post #40</a>
	                </div>
	            </div>
              <div id="likers-container-6631" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="6631"
                     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 #40"></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/853/load_more?page=5">Load more posts (15 remaining)</a>
</div></template></turbo-stream>