<?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: Bruno Bertolini</title>
    <description>The latest articles on DEV Community by Bruno Bertolini (@brunobertolini).</description>
    <link>https://dev.to/brunobertolini</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%2F262086%2Faec54be8-294e-490a-a019-10b3a8502551.jpeg</url>
      <title>DEV Community: Bruno Bertolini</title>
      <link>https://dev.to/brunobertolini</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/brunobertolini"/>
    <language>en</language>
    <item>
      <title>Como REALMENTE o CORS funciona: Entendendo de uma vez por todas</title>
      <dc:creator>Bruno Bertolini</dc:creator>
      <pubDate>Mon, 18 May 2020 14:47:18 +0000</pubDate>
      <link>https://dev.to/brunobertolini/como-realmente-o-cors-funciona-entendendo-de-uma-vez-por-todas-ae0</link>
      <guid>https://dev.to/brunobertolini/como-realmente-o-cors-funciona-entendendo-de-uma-vez-por-todas-ae0</guid>
      <description>&lt;p&gt;Se você já desenvolveu alguma aplicação web, você provavelmente já deu de cara com esse erro no console do navegador:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw0llb8jz0bpw6um7ykdy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw0llb8jz0bpw6um7ykdy.png" alt=" " width="636" height="75"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Esse erro deriva de um mecanismo de segurança implementado pelos navegadores, chamado &lt;strong&gt;&lt;em&gt;Same-Origin Policy&lt;/em&gt;&lt;/strong&gt;, (política de mesma origem). A política de mesma origem restringe a forma de como um documento ou script carregado de uma origem pode interagir com um recurso de outra origem. É um mecanismo crítico de segurança para isolar documentos potencialmente maliciosos, e evitar falsificação de solicitações entre sites, mais conhecido como ataque &lt;strong&gt;CSRF (&lt;em&gt;cross-site request forgery&lt;/em&gt;)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Esse é um tipo de ataque comum, onde um site mal-intencionado tenta tirar proveito do sistema de armazenamento de cookies do navegador. Para cada solicitação de HTTP em um domínio, o navegador anexa todos os cookies HTTP associados a esse domínio. Isso é especialmente útil para autenticação e configuração de sessões. Por exemplo, é possível que você faça login em um aplicativo da web como o &lt;code&gt;instagram.com&lt;/code&gt;. Nesse caso, seu navegador armazenaria um cookie de sessão relevante para o domínio &lt;code&gt;instagram.com&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffra55y5z54doe8ijhdae.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffra55y5z54doe8ijhdae.png" alt=" " width="800" height="199"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Após armazenado, sempre que um usuário acessar novamente o &lt;code&gt;instagram.com&lt;/code&gt;, não será necessário fazer login novamente, já que API reconhecerá o cookie da sessão armazenada, nas requisições futuras (isso se a API usar apenas o cookie como mecanismo de autenticação). &lt;/p&gt;

&lt;p&gt;O único problema é que o navegador inclui automaticamente quaisquer cookies relevantes armazenados para um domínio quando outra solicitação é feita para esse domínio exato. Portanto, se o usuário clicar em um pop-up, por exemplo, abrindo &lt;code&gt;site-do-mal.com&lt;/code&gt;, esse site também tem a capacidade de enviar uma solicitação para &lt;code&gt;instagram.com&lt;/code&gt;. Como a solicitação está indo para o domínio &lt;code&gt;instagram.com&lt;/code&gt;, o navegador inclui os cookies relevantes. O site do mal envia o cookie da sessão e obtém acesso autenticado ao Instagram. Sua conta foi invadida com sucesso com um ataque de falsificação de solicitação entre sites.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbuxtgjlmzk5f64ym3ikf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbuxtgjlmzk5f64ym3ikf.png" alt=" " width="800" height="234"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Felizmente, nessa situação, o navegador intervém e impede que o código malicioso faça uma solicitação de API como esta, e dispara o famoso erro de CORS, que você viu na primeira imagem.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;E que raios então é CORS?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;CORS significa &lt;em&gt;Cross-Origin Resource Sharing&lt;/em&gt; (Compartilhamento de recursos com origens diferentes), e é o padrão que flexibiliza a política de mesma origem, fazendo com que aplicações possam acessar recursos de outras origens.&lt;/p&gt;

&lt;p&gt;Para que o navegador consiga fazer ou não o bloqueio da política de mesma origem, ele precisA verificar se a origem da aplicação web e do recurso externo (url da requisição) são as mesmas. E quando falamos de origem, estamos falando da combinação entre protocolo (http://), domínio (instagram.com) e porta (80 é a porta padrão quando não especificado). &lt;/p&gt;

&lt;p&gt;Então, o navegador adiciona automaticamente, para toda requisição, um cabeçalho informando a origem da aplicação front-end: &lt;code&gt;Origin: http://site-do-mal.com&lt;/code&gt;. O servidor então, baseado nessa requisição, envia uma resposta contendo o cabeçalho &lt;code&gt;Access-Control-Allow-Origin&lt;/code&gt;, que indica se os recursos da resposta podem ser compartilhados com a origem informada.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhp42k4x9aals4wqxszv7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhp42k4x9aals4wqxszv7.png" alt=" " width="800" height="195"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Este cabeçalho pode ter como valor:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Uma origem permitida: &lt;code&gt;Access-Control-Allow-Origin: http://instagram.com&lt;/code&gt;; ou&lt;/li&gt;
&lt;li&gt;Um &lt;code&gt;*&lt;/code&gt;, que indica que qualquer origem pode acessar determinado recurso: &lt;code&gt;Access-Control-Allow-Origin: *&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Nota: É recomendado cuidar com o uso desses cabeçalhos, já que o uso incorreto pode inutilizar a política de mesma origem, facilitando ataques &lt;strong&gt;CSRF&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Com esse cabeçalho "em mãos", o navegador pode comparar com o valor de origem do front-end, e bloquear a solicitação caso os valores não sejam compatíveis.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwuezgld3sy1plh4vf9y8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwuezgld3sy1plh4vf9y8.png" alt=" " width="800" height="289"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Além disso, para métodos de requisição HTTP que podem causar efeitos colaterais nos dados do servidor (em particular, para métodos HTTP diferentes de &lt;a href="https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Methods/GET" rel="noopener noreferrer"&gt;GET&lt;/a&gt; com determinados cabeçalhos, ou para uso de &lt;a href="https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Methods/POST" rel="noopener noreferrer"&gt;POST&lt;/a&gt; com certos &lt;code&gt;Content-types&lt;/code&gt;), a especificação exige que navegadores "pré-enviem" a requisição, solicitando os métodos suportados pelo servidor (e pra informar isso, o servidor utiliza o cabeçalho &lt;code&gt;Access-Control-Allow-Methods&lt;/code&gt;) com um método de requisição HTTP &lt;a href="https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Methods/OPTIONS" rel="noopener noreferrer"&gt;OPTIONS&lt;/a&gt; e, após a "aprovação", o servidor envia a requisição verdadeira com o método de requisição HTTP correto. &lt;/p&gt;

&lt;p&gt;Então, resumindo, CORS nada mais é do que a configuração de cabeçalhos de resposta &lt;code&gt;Access-Control-*&lt;/code&gt; (do lado do servidor), que informam se uma requisição (baseado em origem e métodos HTTP), pode ou não acessar determinado recurso, flexibilizando assim, a política de mesma origem (&lt;strong&gt;&lt;em&gt;Same-Origin Policy&lt;/em&gt;&lt;/strong&gt;), que tem a intenção principal de evitar ataques &lt;strong&gt;CSRF&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>javascript</category>
      <category>security</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Tudo o que você precisa saber sobre JSON Web Tokens</title>
      <dc:creator>Bruno Bertolini</dc:creator>
      <pubDate>Wed, 08 Jan 2020 16:34:01 +0000</pubDate>
      <link>https://dev.to/brunobertolini/tudo-o-que-voce-precisa-saber-sobre-json-web-tokens-5dn7</link>
      <guid>https://dev.to/brunobertolini/tudo-o-que-voce-precisa-saber-sobre-json-web-tokens-5dn7</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--THGxjrQb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/b6xlt9dc50d5cryssjw7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--THGxjrQb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/b6xlt9dc50d5cryssjw7.png" alt="JWT"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O &lt;strong&gt;J&lt;/strong&gt;SON &lt;strong&gt;W&lt;/strong&gt;eb &lt;strong&gt;T&lt;/strong&gt;oken (JWT) é um &lt;strong&gt;padrão&lt;/strong&gt; aberto, que define uma maneira compacta e independente de &lt;strong&gt;transmitir informações com segurança&lt;/strong&gt; entre as partes, utilizando um objeto JSON.&lt;/p&gt;

&lt;p&gt;Os tokens assinados podem verificar a integridade das reivindicações (&lt;em&gt;claims&lt;/em&gt;) contidas nele, enquanto os tokens criptografados ocultam essas reivindicações de outras partes. Quando os tokens são assinados usando pares de chaves pública / privada, a assinatura também certifica que apenas a parte que detém a chave privada é a que o assinou.&lt;/p&gt;

&lt;h2&gt;
  
  
  E onde deveria usá-los?
&lt;/h2&gt;

&lt;p&gt;Dois cenários principais, onde JWTs são úteis:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Autorização&lt;/strong&gt;: este é o cenário mais comum para o uso do JWT. Após o login do usuário, cada solicitação subsequente incluirá o JWT, permitindo que o usuário acesse rotas, serviços e recursos permitidos com esse token. O SSO (Single sign-on) é um recurso que usa amplamente o JWT atualmente, devido à sua pequena sobrecarga e à capacidade de ser facilmente usado em diferentes domínios. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Troca de informações&lt;/strong&gt;: os JSON Web Tokens são uma boa maneira de transmitir informações com segurança entre as partes. Como as JWTs podem ser assinadas (por exemplo, usando pares de chaves públicas / privadas), você pode ter certeza de que os remetentes são quem eles dizem que são. Além disso, como a assinatura é calculada usando o cabeçalho e o payload, você também pode verificar se o conteúdo não foi violado.&lt;/p&gt;

&lt;h2&gt;
  
  
  Certo, e como é a estrutura de um JWT?
&lt;/h2&gt;

&lt;p&gt;JSON Web Tokens são compostos por 3 partes, separadas por um ponto: Cabeçalho (&lt;em&gt;header&lt;/em&gt;), dados (&lt;em&gt;payload&lt;/em&gt;) e assinatura (&lt;em&gt;signature&lt;/em&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  Cabeçalho (&lt;em&gt;header&lt;/em&gt;)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--b33-LKdS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/yos4dgaygpgazrieu1mb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--b33-LKdS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/yos4dgaygpgazrieu1mb.png" alt="Header JWT"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O cabeçalho geralmente consiste em duas partes: o &lt;strong&gt;tipo do token&lt;/strong&gt;, que é JWT, e o &lt;strong&gt;algoritmo de assinatura&lt;/strong&gt; que está sendo usado, como HMAC SHA256 ou RSA.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lDGBI2nZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/opoupkjm59nhfxkacqy0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lDGBI2nZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/opoupkjm59nhfxkacqy0.png" alt="Conteúdo do cabeçalho"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Em seguida, esse JSON é codificado em &lt;strong&gt;Base64Url&lt;/strong&gt; para formar a primeira parte do JWT.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dados (&lt;em&gt;payload&lt;/em&gt;)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OaJqXVDb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/00mlh2sjyglx3osmy5mp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OaJqXVDb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/00mlh2sjyglx3osmy5mp.png" alt="Payload JWT"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O payload é exatamente os &lt;strong&gt;dados&lt;/strong&gt; que você deseja enviar para a outra parte. Geralmente segue um &lt;strong&gt;padrão&lt;/strong&gt; (&lt;em&gt;registered claims&lt;/em&gt;), mas não é obrigatório, portanto aceita qualquer JSON&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HvCLBKJp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/jnt73t4ysx19rmckoxod.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HvCLBKJp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/jnt73t4ysx19rmckoxod.png" alt="Conteúdo do payload"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O payload é então codificado em &lt;strong&gt;Base64Url&lt;/strong&gt; para formar a &lt;strong&gt;segunda parte&lt;/strong&gt; do JWT.&lt;/p&gt;

&lt;h3&gt;
  
  
  Assinatura (&lt;em&gt;signature&lt;/em&gt;)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sYZag0PB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/tpl00cn5admh0blm9bpq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sYZag0PB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/tpl00cn5admh0blm9bpq.png" alt="Assinatura JWT"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para criar a parte da assinatura, é necessário pegar o &lt;strong&gt;cabeçalho&lt;/strong&gt; codificado, a &lt;strong&gt;payload&lt;/strong&gt; codificado, &lt;strong&gt;um segredo&lt;/strong&gt;, o &lt;strong&gt;algoritmo&lt;/strong&gt; especificado no cabeçalho e assinar isso.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---Gj51Hlq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/cfyvniiqrb81gqlafqt6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---Gj51Hlq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/cfyvniiqrb81gqlafqt6.png" alt="Conteúdo da assinatura"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A assinatura é usada para &lt;strong&gt;verificar&lt;/strong&gt; se a mensagem não foi &lt;strong&gt;alterada&lt;/strong&gt; ao longo do caminho e, no caso de tokens assinados com uma &lt;strong&gt;chave privada&lt;/strong&gt;, também pode verificar se o remetente da JWT &lt;strong&gt;é quem diz ser&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Esse conteúdo também está lá no &lt;a href="http://bit.ly/30cofQt"&gt;insta da codar.me&lt;/a&gt;, segue lá, que tenho postado conteúdo com frequência! Ah, e se inscreve no &lt;a href="http://bit.ly/2FyBaCF"&gt;canal do youtube&lt;/a&gt; pra conteúdos mais aprofundados! :)&lt;/p&gt;
&lt;/blockquote&gt;

</description>
    </item>
    <item>
      <title>Gerenciamento de autenticação no front-end</title>
      <dc:creator>Bruno Bertolini</dc:creator>
      <pubDate>Mon, 18 Nov 2019 11:41:34 +0000</pubDate>
      <link>https://dev.to/brunobertolini/gerenciamento-de-autenticacao-no-front-end-2ieo</link>
      <guid>https://dev.to/brunobertolini/gerenciamento-de-autenticacao-no-front-end-2ieo</guid>
      <description>&lt;p&gt;Existem várias formas de fazer o gerenciamento de autenticação no front. A forma que eu vou mostrar aqui é simples, porém robusta, e pode ser utilizada tanto no React Native quanto no React web. &lt;/p&gt;

&lt;p&gt;Faremos isso com React Native, utilizando o Context API pra criar um estado global na nossa aplicação, e AsyncStorage pra persistência de dados.&lt;/p&gt;

&lt;h2&gt;
  
  
  A tela de login
&lt;/h2&gt;

&lt;p&gt;Precisamos pensar como esse gerenciamento vai funcionar. Eu gosto de começar de cima pra baixo o desenvolvimento, da camada mais alta até a mais baixa, isso me dá uma clareza maior do que precisa ser feito. &lt;/p&gt;

&lt;p&gt;Nesse caso, a camada mais alta é a nossa tela de login. Então o que eu preciso fazer quando o usuário apertar o botão &lt;em&gt;Entrar&lt;/em&gt;? Basicamente, duas coisas:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pegar os dados do form e enviar pra uma api, que vai me retornar o usuário logado e um token para as próximas requisições&lt;/li&gt;
&lt;li&gt;Pegar os dados retornados da api, e jogar eles em um estado global, pra que seja acessado de qualquer parte da aplicação.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Então, teríamos um componente de login, semelhante a isto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Login&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formik&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useFormik&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;onSubmit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;values&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;setStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Show, agora eu sei que eu preciso criar um &lt;code&gt;setStore&lt;/code&gt;, que vai gerenciar meu estado global, que é a próxima etapa.&lt;/p&gt;

&lt;h2&gt;
  
  
  Global Store
&lt;/h2&gt;

&lt;p&gt;Podemos fazer a global store de várias formas diferentes, seja utilizando redux, mobx, ou qualquer outra ferramenta de gerenciamento de estado. Aqui, vamos utilizar o Context API, que resolve muito bem o problema e serve tanto para aplicações pequenas quanto maiores.&lt;/p&gt;

&lt;p&gt;Vamos criar um simples context provider que utilizará como valor, um &lt;code&gt;useState&lt;/code&gt;, assim conseguiremos capturar o estado atual da nossa store em qualquer componente, bem como alterá-lo.&lt;/p&gt;

&lt;p&gt;Crie um arquivo chamado &lt;code&gt;store.js&lt;/code&gt;, faça o seguinte:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// Aqui criamos o contexto, já com um valor semelhante &lt;/span&gt;
&lt;span class="c1"&gt;// ao que precisaremos posteriormente&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;StoreContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createContext&lt;/span&gt;&lt;span class="p"&gt;([{},&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{}])&lt;/span&gt;

&lt;span class="c1"&gt;// E aqui encapsulamos o provider pra conseguir passar o retorno &lt;/span&gt;
&lt;span class="c1"&gt;// do `useState` como valor&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;StoreProvider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// criando um state com um objeto vazio como valor inicial&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;({})&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;StoreContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Provider&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/StoreContext.Provider&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Nota: se quiser estudar mais sobre context api, dá uma olhada na &lt;a href="https://pt-br.reactjs.org/docs/context.html"&gt;doc oficial&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Certo, criado nosso global store provider, precisamos usar ele no componente principal da aplicação (geralmente &lt;code&gt;index.js&lt;/code&gt;, ou melhor ainda &lt;code&gt;src/index.js&lt;/code&gt;), para que todos os componentes abaixo dele tenham acesso ao &lt;code&gt;StoreContext&lt;/code&gt; e possam recuperar e manipular nossa store.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AppRegistry&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;appName&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./app.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./src&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;StoreProvider&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/StoreProvider&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;AppRegistry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;registerComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;appName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;Root&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Agora, qualquer componente pode acessar o contexto da store, mas, como fazer isso?&lt;/p&gt;

&lt;p&gt;Bom, poderíamos fazer exportando nosso &lt;code&gt;StoreContext&lt;/code&gt; e utilizando &lt;code&gt;useContext&lt;/code&gt; assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;StoreContext&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./store.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setStore&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;StoreContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Mas eu aconselho criarmos um hook especifico pra acessar a store, assim temos mais flexibilidade de criação e manutenção, podendo estender as funcionalidades do nosso novo hook facilmente. Então no &lt;code&gt;store.js&lt;/code&gt;, criamos o hook:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setStore&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;StoreContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setStore&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Agora que temos login jogando na nossa store os dados do usuário, ao iniciar a aplicação precisamos verificar se um usuário está logado, e redirecionar ele para a tela correspondente (&lt;em&gt;home&lt;/em&gt; se estiver logado, login se não estiver). Vamos fazer isso no componente que define as rotas principais, porém nesse momento ele vai ser criado dentro do arquivo &lt;code&gt;src/index.js&lt;/code&gt; e vamos chamá-lo de &lt;code&gt;Router&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useStore&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Home&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Login&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Lembra que criamos nossa store com um objeto vazio como valor inicial? Pois bem, nesse momento, ao verificar se nossa store possui uma prop &lt;code&gt;token&lt;/code&gt;, teremos como resultado false, portanto, nossa tela de login será mostrada. Posteriormente, quando o usuário fizer login e nosso componente de login fizer &lt;code&gt;setStore&lt;/code&gt; com o token, automaticamente o nosso router vai ser re-renderizado, dessa vez contento &lt;code&gt;store.token&lt;/code&gt;, mostrando assim a tela inicial (Home) no lugar de login.&lt;/p&gt;

&lt;p&gt;Pronto, já temos nosso gerenciamento de autenticação, certo? Errado! Ainda falta uma etapa importante. Toda vez que o usuário fechar o app e abrir novamente, nós perdemos os dados em memória, portanto, mesmo que ele tenha feito login recentemente, ele será redirecionado para &lt;code&gt;Login&lt;/code&gt;. Então, como podemos resolver isso?&lt;/p&gt;

&lt;h2&gt;
  
  
  Persistência e reidratação de memória
&lt;/h2&gt;

&lt;p&gt;Quando um app é fechado, de um modo geral, ele apaga todas as variáveis da memória, portanto na próxima execução do app não saberemos quem estava logado. Por isso precisamos persistir essas informações em outro local (como um arquivo, banco de dados local ou remoto), e fazer a reidratação para que o app volta ao estado em que estava logo antes de ser fechado.&lt;/p&gt;

&lt;p&gt;Para isso, vamos utilizar o &lt;em&gt;async storage&lt;/em&gt; pra react native (pra web você pode utilizar o &lt;em&gt;local storage&lt;/em&gt;, com a mesma abordagem).&lt;/p&gt;

&lt;p&gt;Vamos iniciar importando o &lt;code&gt;useAsyncStorage&lt;/code&gt; e persistindo toda alteração da nossa store nele. Dentro do &lt;code&gt;&amp;lt;StoreProvider&amp;gt;&lt;/code&gt; vamos fazer o seguinte:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useAsyncStorage&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@react-native-community/async-storage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;StoreProvider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;({})&lt;/span&gt;

  &lt;span class="c1"&gt;// Aqui definimos que a "key" usada no async storage será "store"&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;setItem&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useAsyncStorage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;store&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;// então usamos o useEffect pra escutar as alterações do state,&lt;/span&gt;
  &lt;span class="c1"&gt;// e executar setItem, que vai persistir  nosso estado&lt;/span&gt;
  &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nx"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Agora quando executarmos o &lt;code&gt;setStore&lt;/code&gt; lá na tela de login, o &lt;code&gt;StoreProvider&lt;/code&gt; vai persistir isso no &lt;em&gt;async storage&lt;/em&gt;. Porém ainda precisamos reidratar a memoria quando o app for aberto, então pra isso, faremos outro &lt;code&gt;useEffect&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;StoreProvider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getItem&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useAsyncStorage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;store&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rehydrate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;rehydrate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Ou seja, toda vez que o app foi aberto, e o react fizer &lt;em&gt;mount&lt;/em&gt; do nosso StoreProvider, a função de &lt;code&gt;rehydrate&lt;/code&gt; será executada, pegando todos os dados do async storage e jogando na memoria do nosso state.&lt;/p&gt;

&lt;p&gt;Acontece que não sabemos quanto tempo esse processo de &lt;em&gt;rehydrate&lt;/em&gt; pode levar, ocasionando um &lt;em&gt;lag&lt;/em&gt; na checagem do nosso router, que vai mostrar a tela de login antes de fazer o redirecionamento pra tela Home, pois inicialmente não temos o token na store. Então pra resolver esse problema, precisamos adicionar na nossa store uma prop informando que o processo de &lt;em&gt;rehydrate&lt;/em&gt; ainda está em execução, para que um loading seja mostrado na tela antes de fazermos a verificação de usuário logado. Nesse caso nossa store final fica assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useAsyncStorage&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@react-native-community/async-storage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;StoreContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createContext&lt;/span&gt;&lt;span class="p"&gt;([{},&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{}])&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;StoreContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;StoreProvider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setItem&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useAsyncStorage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;store&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;rehydrated&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rehydrate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prev&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;...(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
      &lt;span class="na"&gt;rehydrated&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}))&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;rehydrate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;

  &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;StoreContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Provider&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/StoreContext.Provider&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Verifique que adicionamos um estado inicial com &lt;code&gt;rehydrated: false&lt;/code&gt;, e no método de &lt;em&gt;rehydrate&lt;/em&gt;, colocamos &lt;code&gt;rehydrated: true&lt;/code&gt; pra informar que o processo de reidratação foi concluído.&lt;/p&gt;

&lt;p&gt;Ainda temos que alterar nosso login, pra mesclar as informações na store, em vez de substituí-las.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;const Login = () =&amp;gt; {
&lt;/span&gt;  const formik = useFormik({
    onSubmit = async values =&amp;gt; {
      try {
        const { data } = await api.login(values)
&lt;span class="gd"&gt;-        setStore(data)
&lt;/span&gt;&lt;span class="gi"&gt;+        setStore(prevState =&amp;gt; ({...prevState, auth: data })
&lt;/span&gt;      } catch (error) { }
    }
  })

  ...
&lt;span class="err"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Perceba que agora nossa store passa a ter os dados de autenticação nomeados pra &lt;code&gt;auth&lt;/code&gt;, então nosso componente &lt;code&gt;Router&lt;/code&gt; precisa se adaptar a isso, além de verificar se o processo de &lt;em&gt;rehydrate&lt;/em&gt; já terminou ou não:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rehydrated&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useStore&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;rehydrated&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Loading&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;auth&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Home&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Login&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;E pronto, temos um gerenciamento de autenticação utilizando um estado global com context api e persistência!&lt;/p&gt;

&lt;p&gt;Você pode ver o &lt;a href="https://youtu.be/gsJ6krEJTGM"&gt;vídeo&lt;/a&gt; onde eu explico essa implementação mais detalhadamente, e pode acessar o &lt;a href="https://github.com/CodarMe/rn-auth-manager"&gt;repo&lt;/a&gt; com o projeto desenvolvido durante a gravação do vídeo.&lt;/p&gt;

</description>
      <category>react</category>
      <category>reactnative</category>
    </item>
  </channel>
</rss>
