Skip to content

Commit

Permalink
Deployed 787793b with MkDocs version: 1.5.3
Browse files Browse the repository at this point in the history
  • Loading branch information
dunossauro committed Feb 28, 2024
1 parent fed8663 commit b32082e
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 96 deletions.
24 changes: 12 additions & 12 deletions 06/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -1145,8 +1145,8 @@ <h2 id="como-funciona-o-jwt">Como funciona o JWT</h2>
Servidor-&gt;&gt;Cliente: Verifica o token JWT e processa a solicitação</code></pre>
<p>Nos próximos tópicos, vamos detalhar como podemos gerar e verificar tokens JWT em nossa aplicação FastAPI, bem como adicionar autenticação e autorização aos nossos endpoints.</p>
<h2 id="gerando-tokens-jwt">Gerando tokens JWT</h2>
<p>Para gerar tokens JWT, precisamos de duas bibliotecas extras: <code>python-jose</code> e <code>passlib</code>. A primeira será usada para a geração do token, enquanto a segunda será usada para criptografar as senhas dos usuários. Para instalá-las, execute o seguinte comando no terminal:</p>
<div class="language-shell highlight"><span class="filename">$ Execução no terminal!</span><pre><span></span><code><span id="__span-4-1"><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a>poetry<span class="w"> </span>add<span class="w"> </span><span class="s2">"python-jose[cryptography]"</span><span class="w"> </span><span class="s2">"passlib[bcrypt]"</span>
<p>Para gerar tokens JWT, precisamos de duas bibliotecas extras: <code>pyjwt</code> e <code>passlib</code>. A primeira será usada para a geração do token, enquanto a segunda será usada para criptografar as senhas dos usuários. Para instalá-las, execute o seguinte comando no terminal:</p>
<div class="language-shell highlight"><span class="filename">$ Execução no terminal!</span><pre><span></span><code><span id="__span-4-1"><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a>poetry<span class="w"> </span>add<span class="w"> </span>pyjwt<span class="w"> </span><span class="s2">"passlib[bcrypt]"</span>
</span></code></pre></div>
<p>Agora, criaremos uma função para gerar nossos tokens JWT. Criaremos um novo arquivo para gerenciar a segurança: <code>security.py</code>. Nesse arquivo iniciaremos a geração dos tokens:</p>
<div class="language-python highlight"><table class="highlighttable"><tr><th colspan="2" class="filename"><span class="filename">fast_zero/security.py</span></th></tr><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-5-1"> 1</a></span>
Expand All @@ -1167,7 +1167,7 @@ <h2 id="gerando-tokens-jwt">Gerando tokens JWT</h2>
<span class="normal"><a href="#__codelineno-5-16">16</a></span>
<span class="normal"><a href="#__codelineno-5-17">17</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-5-1"><a id="__codelineno-5-1" name="__codelineno-5-1"></a><span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">datetime</span><span class="p">,</span> <span class="n">timedelta</span>
</span><span id="__span-5-2"><a id="__codelineno-5-2" name="__codelineno-5-2"></a>
</span><span id="__span-5-3"><a id="__codelineno-5-3" name="__codelineno-5-3"></a><span class="kn">from</span> <span class="nn">jose</span> <span class="kn">import</span> <span class="n">jwt</span>
</span><span id="__span-5-3"><a id="__codelineno-5-3" name="__codelineno-5-3"></a><span class="kn">from</span> <span class="nn">jwt</span> <span class="kn">import</span> <span class="n">encode</span>
</span><span id="__span-5-4"><a id="__codelineno-5-4" name="__codelineno-5-4"></a><span class="kn">from</span> <span class="nn">passlib.context</span> <span class="kn">import</span> <span class="n">CryptContext</span>
</span><span id="__span-5-5"><a id="__codelineno-5-5" name="__codelineno-5-5"></a>
</span><span id="__span-5-6"><a id="__codelineno-5-6" name="__codelineno-5-6"></a><span class="n">SECRET_KEY</span> <span class="o">=</span> <span class="s1">'your-secret-key'</span> <span class="c1"># Isso é provisório, vamos ajustar!</span>
Expand All @@ -1180,13 +1180,13 @@ <h2 id="gerando-tokens-jwt">Gerando tokens JWT</h2>
</span><span id="__span-5-13"><a id="__codelineno-5-13" name="__codelineno-5-13"></a> <span class="n">to_encode</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
</span><span id="__span-5-14"><a id="__codelineno-5-14" name="__codelineno-5-14"></a> <span class="n">expire</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">utcnow</span><span class="p">()</span> <span class="o">+</span> <span class="n">timedelta</span><span class="p">(</span><span class="n">minutes</span><span class="o">=</span><span class="n">ACCESS_TOKEN_EXPIRE_MINUTES</span><span class="p">)</span>
</span><span id="__span-5-15"><a id="__codelineno-5-15" name="__codelineno-5-15"></a> <span class="n">to_encode</span><span class="o">.</span><span class="n">update</span><span class="p">({</span><span class="s1">'exp'</span><span class="p">:</span> <span class="n">expire</span><span class="p">})</span>
</span><span id="__span-5-16"><a id="__codelineno-5-16" name="__codelineno-5-16"></a> <span class="n">encoded_jwt</span> <span class="o">=</span> <span class="n">jwt</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="n">to_encode</span><span class="p">,</span> <span class="n">SECRET_KEY</span><span class="p">,</span> <span class="n">algorithm</span><span class="o">=</span><span class="n">ALGORITHM</span><span class="p">)</span>
</span><span id="__span-5-16"><a id="__codelineno-5-16" name="__codelineno-5-16"></a> <span class="n">encoded_jwt</span> <span class="o">=</span> <span class="n">encode</span><span class="p">(</span><span class="n">to_encode</span><span class="p">,</span> <span class="n">SECRET_KEY</span><span class="p">,</span> <span class="n">algorithm</span><span class="o">=</span><span class="n">ALGORITHM</span><span class="p">)</span>
</span><span id="__span-5-17"><a id="__codelineno-5-17" name="__codelineno-5-17"></a> <span class="k">return</span> <span class="n">encoded_jwt</span>
</span></code></pre></div></td></tr></table></div>
<p>A função <code>create_access_token</code> é responsável por criar um novo token JWT que será usado para autenticar o usuário. Ela recebe um dicionário de dados, adiciona um tempo de expiração ao token (baseado na constante <code>ACCESS_TOKEN_EXPIRE_MINUTES</code>). Esses dados, em conjunto, formam o <strong>payload</strong> do JWT. Em seguida, usa a biblioteca <code>jose</code> para codificar essas informações em um token JWT, que é então retornado.</p>
<p>A função <code>create_access_token</code> é responsável por criar um novo token JWT que será usado para autenticar o usuário. Ela recebe um dicionário de dados, adiciona um tempo de expiração ao token (baseado na constante <code>ACCESS_TOKEN_EXPIRE_MINUTES</code>). Esses dados, em conjunto, formam o <strong>payload</strong> do JWT. Em seguida, usa a biblioteca <code>pyjwt</code> para codificar essas informações em um token JWT, que é então retornado.</p>
<p>Note que a constante <code>SECRET_KEY</code> é usada para assinar o token, e o algoritmo <code>HS256</code> é usado para a codificação. Em um cenário de produção, você deve manter a <code>SECRET_KEY</code> em um local seguro e não expô-la em seu código.</p>
<h3 id="testando-a-geracao-de-tokens">Testando a geração de tokens</h3>
<p>Embora esse código será coberto no futuro com a utilização do token, é interessante criarmos um teste para essa função com uma finalidade puramente didática. De forma que vejamos os tokens gerados pelo <code>jose</code> e interagirmos com ele.</p>
<p>Embora esse código será coberto no futuro com a utilização do token, é interessante criarmos um teste para essa função com uma finalidade puramente didática. De forma que vejamos os tokens gerados pelo <code>pyjwt</code> e interagirmos com ele.</p>
<p>Com isso criaremos um arquivo chamado <code>tests/test_security.py</code> para efetuar esse teste:</p>
<div class="language-python highlight"><table class="highlighttable"><tr><th colspan="2" class="filename"><span class="filename">tests/test_security.py</span></th></tr><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-6-1"> 1</a></span>
<span class="normal"><a href="#__codelineno-6-2"> 2</a></span>
Expand All @@ -1200,7 +1200,7 @@ <h3 id="testando-a-geracao-de-tokens">Testando a geração de tokens</h3>
<span class="normal"><a href="#__codelineno-6-10">10</a></span>
<span class="normal"><a href="#__codelineno-6-11">11</a></span>
<span class="normal"><a href="#__codelineno-6-12">12</a></span>
<span class="normal"><a href="#__codelineno-6-13">13</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-6-1"><a id="__codelineno-6-1" name="__codelineno-6-1"></a><span class="kn">from</span> <span class="nn">jose</span> <span class="kn">import</span> <span class="n">jwt</span>
<span class="normal"><a href="#__codelineno-6-13">13</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-6-1"><a id="__codelineno-6-1" name="__codelineno-6-1"></a><span class="kn">from</span> <span class="nn">jwt</span> <span class="kn">import</span> <span class="n">decode</span>
</span><span id="__span-6-2"><a id="__codelineno-6-2" name="__codelineno-6-2"></a>
</span><span id="__span-6-3"><a id="__codelineno-6-3" name="__codelineno-6-3"></a><span class="kn">from</span> <span class="nn">fast_zero.security</span> <span class="kn">import</span> <span class="n">SECRET_KEY</span><span class="p">,</span> <span class="n">create_access_token</span>
</span><span id="__span-6-4"><a id="__codelineno-6-4" name="__codelineno-6-4"></a>
Expand All @@ -1209,7 +1209,7 @@ <h3 id="testando-a-geracao-de-tokens">Testando a geração de tokens</h3>
</span><span id="__span-6-7"><a id="__codelineno-6-7" name="__codelineno-6-7"></a> <span class="n">data</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'test'</span><span class="p">:</span> <span class="s1">'test'</span><span class="p">}</span>
</span><span id="__span-6-8"><a id="__codelineno-6-8" name="__codelineno-6-8"></a> <span class="n">token</span> <span class="o">=</span> <span class="n">create_access_token</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
</span><span id="__span-6-9"><a id="__codelineno-6-9" name="__codelineno-6-9"></a>
</span><span id="__span-6-10"><a id="__codelineno-6-10" name="__codelineno-6-10"></a> <span class="n">decoded</span> <span class="o">=</span> <span class="n">jwt</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="n">token</span><span class="p">,</span> <span class="n">SECRET_KEY</span><span class="p">,</span> <span class="n">algorithms</span><span class="o">=</span><span class="p">[</span><span class="s1">'HS256'</span><span class="p">])</span>
</span><span id="__span-6-10"><a id="__codelineno-6-10" name="__codelineno-6-10"></a> <span class="n">decoded</span> <span class="o">=</span> <span class="n">decode</span><span class="p">(</span><span class="n">token</span><span class="p">,</span> <span class="n">SECRET_KEY</span><span class="p">,</span> <span class="n">algorithms</span><span class="o">=</span><span class="p">[</span><span class="s1">'HS256'</span><span class="p">])</span>
</span><span id="__span-6-11"><a id="__codelineno-6-11" name="__codelineno-6-11"></a>
</span><span id="__span-6-12"><a id="__codelineno-6-12" name="__codelineno-6-12"></a> <span class="k">assert</span> <span class="n">decoded</span><span class="p">[</span><span class="s1">'test'</span><span class="p">]</span> <span class="o">==</span> <span class="n">data</span><span class="p">[</span><span class="s1">'test'</span><span class="p">]</span>
</span><span id="__span-6-13"><a id="__codelineno-6-13" name="__codelineno-6-13"></a> <span class="k">assert</span> <span class="n">decoded</span><span class="p">[</span><span class="s1">'exp'</span><span class="p">]</span> <span class="c1"># Testa se o valor de exp foi adicionado ao token</span>
Expand Down Expand Up @@ -1484,7 +1484,7 @@ <h2 id="protegendo-os-endpoints">Protegendo os Endpoints</h2>
</span><span id="__span-23-2"><a id="__codelineno-23-2" name="__codelineno-23-2" href="#__codelineno-23-2"></a>
</span><span id="__span-23-3"><a id="__codelineno-23-3" name="__codelineno-23-3" href="#__codelineno-23-3"></a><span class="kn">from</span> <span class="nn">fastapi</span> <span class="kn">import</span> <span class="n">Depends</span><span class="p">,</span> <span class="n">HTTPException</span><span class="p">,</span> <span class="n">status</span>
</span><span id="__span-23-4"><a id="__codelineno-23-4" name="__codelineno-23-4" href="#__codelineno-23-4"></a><span class="kn">from</span> <span class="nn">fastapi.security</span> <span class="kn">import</span> <span class="n">OAuth2PasswordBearer</span>
</span><span id="__span-23-5"><a id="__codelineno-23-5" name="__codelineno-23-5" href="#__codelineno-23-5"></a><span class="kn">from</span> <span class="nn">jose</span> <span class="kn">import</span> <span class="n">JWTError</span><span class="p">,</span> <span class="n">jwt</span>
</span><span id="__span-23-5"><a id="__codelineno-23-5" name="__codelineno-23-5" href="#__codelineno-23-5"></a><span class="kn">from</span> <span class="nn">jwt</span> <span class="kn">import</span> <span class="n">DecodeError</span><span class="p">,</span> <span class="n">decode</span><span class="p">,</span> <span class="n">encode</span>
</span><span id="__span-23-6"><a id="__codelineno-23-6" name="__codelineno-23-6" href="#__codelineno-23-6"></a><span class="kn">from</span> <span class="nn">passlib.context</span> <span class="kn">import</span> <span class="n">CryptContext</span>
</span><span id="__span-23-7"><a id="__codelineno-23-7" name="__codelineno-23-7" href="#__codelineno-23-7"></a><span class="kn">from</span> <span class="nn">sqlalchemy</span> <span class="kn">import</span> <span class="n">select</span>
</span><span id="__span-23-8"><a id="__codelineno-23-8" name="__codelineno-23-8" href="#__codelineno-23-8"></a><span class="kn">from</span> <span class="nn">sqlalchemy.orm</span> <span class="kn">import</span> <span class="n">Session</span>
Expand All @@ -1508,12 +1508,12 @@ <h2 id="protegendo-os-endpoints">Protegendo os Endpoints</h2>
</span><span id="__span-23-26"><a id="__codelineno-23-26" name="__codelineno-23-26" href="#__codelineno-23-26"></a> <span class="p">)</span>
</span><span id="__span-23-27"><a id="__codelineno-23-27" name="__codelineno-23-27" href="#__codelineno-23-27"></a>
</span><span id="__span-23-28"><a id="__codelineno-23-28" name="__codelineno-23-28" href="#__codelineno-23-28"></a> <span class="k">try</span><span class="p">:</span>
</span><span id="__span-23-29"><a id="__codelineno-23-29" name="__codelineno-23-29" href="#__codelineno-23-29"></a> <span class="n">payload</span> <span class="o">=</span> <span class="n">jwt</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="n">token</span><span class="p">,</span> <span class="n">SECRET_KEY</span><span class="p">,</span> <span class="n">algorithms</span><span class="o">=</span><span class="p">[</span><span class="n">ALGORITHM</span><span class="p">])</span>
</span><span id="__span-23-29"><a id="__codelineno-23-29" name="__codelineno-23-29" href="#__codelineno-23-29"></a> <span class="n">payload</span> <span class="o">=</span> <span class="n">decode</span><span class="p">(</span><span class="n">token</span><span class="p">,</span> <span class="n">SECRET_KEY</span><span class="p">,</span> <span class="n">algorithms</span><span class="o">=</span><span class="p">[</span><span class="n">ALGORITHM</span><span class="p">])</span>
</span><span id="__span-23-30"><a id="__codelineno-23-30" name="__codelineno-23-30" href="#__codelineno-23-30"></a> <span class="n">username</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="n">payload</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'sub'</span><span class="p">)</span>
</span><span id="__span-23-31"><a id="__codelineno-23-31" name="__codelineno-23-31" href="#__codelineno-23-31"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">username</span><span class="p">:</span>
</span><span id="__span-23-32"><a id="__codelineno-23-32" name="__codelineno-23-32" href="#__codelineno-23-32"></a> <span class="k">raise</span> <span class="n">credentials_exception</span>
</span><span id="__span-23-33"><a id="__codelineno-23-33" name="__codelineno-23-33" href="#__codelineno-23-33"></a> <span class="n">token_data</span> <span class="o">=</span> <span class="n">TokenData</span><span class="p">(</span><span class="n">username</span><span class="o">=</span><span class="n">username</span><span class="p">)</span>
</span><span id="__span-23-34"><a id="__codelineno-23-34" name="__codelineno-23-34" href="#__codelineno-23-34"></a> <span class="k">except</span> <span class="n">JWTError</span><span class="p">:</span>
</span><span id="__span-23-34"><a id="__codelineno-23-34" name="__codelineno-23-34" href="#__codelineno-23-34"></a> <span class="k">except</span> <span class="n">DecodeError</span><span class="p">:</span>
</span><span id="__span-23-35"><a id="__codelineno-23-35" name="__codelineno-23-35" href="#__codelineno-23-35"></a> <span class="k">raise</span> <span class="n">credentials_exception</span>
</span><span id="__span-23-36"><a id="__codelineno-23-36" name="__codelineno-23-36" href="#__codelineno-23-36"></a>
</span><span id="__span-23-37"><a id="__codelineno-23-37" name="__codelineno-23-37" href="#__codelineno-23-37"></a> <span class="n">user</span> <span class="o">=</span> <span class="n">session</span><span class="o">.</span><span class="n">scalar</span><span class="p">(</span>
Expand Down Expand Up @@ -1697,7 +1697,7 @@ <h2 id="conclusao">Conclusão</h2>
<span class="md-icon" title="Última atualização">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1-2.1-2M12.5 7v5.2l4 2.4-1 1L11 13V7h1.5M11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2v1.8Z"/></svg>
</span>
<span class="git-revision-date-localized-plugin git-revision-date-localized-plugin-date">February 7, 2024</span>
<span class="git-revision-date-localized-plugin git-revision-date-localized-plugin-date">February 28, 2024</span>
</span>


Expand Down
Loading

0 comments on commit b32082e

Please sign in to comment.