<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Thibault Couraud</title>
    <description>The latest articles on DEV Community by Thibault Couraud (@thibaultcouraud).</description>
    <link>https://dev.to/thibaultcouraud</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F707579%2F5e617633-ea77-4e42-a9c9-a4eacdb58edd.jpeg</url>
      <title>DEV Community: Thibault Couraud</title>
      <link>https://dev.to/thibaultcouraud</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thibaultcouraud"/>
    <language>en</language>
    <item>
      <title>OAuth Tokens &amp; Potlock gem</title>
      <dc:creator>Thibault Couraud</dc:creator>
      <pubDate>Fri, 17 Sep 2021 15:57:25 +0000</pubDate>
      <link>https://dev.to/potloc/oauth-tokens-potlock-gem-4o79</link>
      <guid>https://dev.to/potloc/oauth-tokens-potlock-gem-4o79</guid>
      <description>&lt;h2&gt;
  
  
  A bit of context 👋🏽
&lt;/h2&gt;

&lt;p&gt;When calling Apis that use OAuth as authentication process, you need to generate an &lt;strong&gt;access token&lt;/strong&gt;. And to get an access token, we have to use a &lt;strong&gt;refresh token&lt;/strong&gt; stored in the server.&lt;/p&gt;

&lt;p&gt;Here's the OAuth workflow to generate this &lt;strong&gt;access token&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4IKg56yw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://developer.ebay.com/api-docs/res/resources/images/ebay-rest/refresh_token_650x460.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4IKg56yw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://developer.ebay.com/api-docs/res/resources/images/ebay-rest/refresh_token_650x460.png" alt="https://developer.ebay.com/api-docs/res/resources/images/ebay-rest/refresh_token_650x460.png" width="650" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Image source: developer.ebay.com&lt;/em&gt;&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  So what was the need? 🤔
&lt;/h2&gt;

&lt;p&gt;An access token &lt;strong&gt;expires after a certain time&lt;/strong&gt;, in minutes, hours, days, depending on the provider. So we need to refresh it time to time.&lt;/p&gt;

&lt;p&gt;The issue was that different processes were refreshing the token at the same time, &lt;strong&gt;invalidating other's freshly generated access token&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So we had to find a way to be sure that &lt;strong&gt;only one process can refresh the token&lt;/strong&gt;. &lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Here comes the gem 🚀
&lt;/h2&gt;

&lt;p&gt;Today we introduce our new gem: &lt;strong&gt;Potlock - a Distributed Read-Write lock using redis&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(available on Github here: &lt;a href="https://github.com/potloc/potlock/"&gt;GitHub - potloc/potlock&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This brand new gem only allows one simultaneous reader or writer. And if the lock is taken, any readers or writers who come along will have to wait.&lt;/p&gt;

&lt;p&gt;Here's an example of how we use this gem at &lt;a href="https://www.potloc.com/"&gt;Potloc&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;token&lt;/span&gt;
  &lt;span class="n"&gt;lock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Potlock&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;key: &lt;/span&gt;&lt;span class="s2"&gt;"snapchat_api"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;# Fetch the token, refresh it if not present&lt;/span&gt;
  &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;refresh_token!&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;# A token is invalid when empty or expired&lt;/span&gt;
  &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="no"&gt;InvalidToken&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;valid?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="n"&gt;token&lt;/span&gt;
&lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;InvalidToken&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_e&lt;/span&gt;
  &lt;span class="c1"&gt;# Generate and save a new token&lt;/span&gt;
  &lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;refresh_token!&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way, we are sure that all the processes will have &lt;strong&gt;the same valid access token and won't overwrite it at the same time&lt;/strong&gt; 🎉&lt;br&gt;
&lt;br&gt;&lt;br&gt;
&lt;em&gt;Interested in what we do at &lt;a href="https://www.potloc.com/"&gt;Potloc&lt;/a&gt;? Come join us! &lt;a href="https://jobs.lever.co/Potloc"&gt;We are hiring&lt;/a&gt; 🚀&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>oauth</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
