HTTP

Termos comuns de segurança: HTTPS

Com certeza, ao navegar na internet, você já viu no começo da URL o protocolo HTTPS. Mas, você sabe para que serve e como funciona esse protocolo?

Primeiramente, antes de falarmos sobre HTTPS precisamos entender o que é o HTTP.

O que é HTTP?

HTTP é uma sigla para Hypertext Transfer Protocol (em português, Protocolo de Transferência de Hipertexto).

Trata-se do principal protocolo de comunicação utilizado para transferência de dados entre computadores utilizados na internet. Essa comunicação entre as máquinas envolvidas ocorre baseada em informações que trafegam como texto.

Para que esse sistema de comunicação em rede baseada em textos seja possível, o HTTP precisa trabalhar em conjunto com o TCP (Transmission Control Protocol), responsável pela transferência das informações; e com o protocolo IP (Internet Protocol), que cuida do encaminhamento dos dados. Juntos, os protocolos TCP e IP formam o modelo TCP/IP, modelo sob o qual o protocolo HTTP é executado.

HTTP - Fundamentos
Curso de HTTP - Fundamentos
CONHEÇA O CURSO

Como o HTTP funciona?

A comunicação realizada pelo HTTP segue o modelo cliente-servidor, baseando-se nos conceitos de request (pedido) e response (resposta). Um request corresponde a um pedido feito ao servidor. Uma mensagem de requisição do cliente é composta pelos seguintes campos de maneira geral:

Linha de pedido: formada pelo identificador do método HTTP (GET, POST, PUT, DELETE, etc.), URI do recurso (endereço para o qual será enviado o pedido) e versão do protocolo (geralmente, HTTP 1.1 e HTTP 2);

Cabeçalho: contém meta-informações sobre a requisição, como a identificação do cliente que está fazendo o pedido;

Corpo: contém os dados da requisição.

Já o response corresponde à resposta que é enviada pelo servidor. Geralmente, ele é composto dos seguintes componentes:

Linha de status: contém informações como a versão do protocolo utilizado no servidor, código numérico do status da resposta e o texto associado ao status;

Cabeçalho: é bem similar ao cabeçalho do pedido, ou seja, contém meta-informações e informações adicionais sobre o seu pedido e conteúdo de resposta;

Corpo: conteúdo de resposta para a requisição realizada (no caso de acesso a um site, seria o HTML para que o browser renderize a página, por exemplo).

De fato, essa comunicação baseada nesse modelo cliente/servidor é extremamente rápida e eficiente. Porém, existe um problema grande: toda essa comunicação que ocorre através do protocolo HTTP é baseada em texto puro, o que é completamente inseguro. E aqui entra o HTTPS.

HTTPS

O HTTPS é uma extensão do protocolo HTTP com a adição de uma camada de segurança na comunicação entre cliente/servidor, fazendo o uso do protocolo SSL (Secure Socket Layer).

Essa camada adicional permite que os dados sejam transmitidos por meio de uma conexão criptografada, além de garantir a verificação da autenticidade do servidor e do cliente por meio de certificados digitais.

Essas técnicas de criptografia servem para proteger os dados trafegados contra ataques de terceiros, minimizando bastante a possibilidade de que outras pessoas consigam ter acesso a informações que são trafegadas.

Por exemplo, quando você está em uma página servida através de HTTPS onde você precisa colocar seus dados (como uma página de login, por exemplo), esses dados são criptografados através de certificados digitais.

Nesse sentido, o fato de que o HTTPS em conjunto com o SSL pode prover aspectos de segurança adicionais faz com que até mesmo sua utilização seja praticamente obrigatória em alguns nichos (em e-commerces, por exemplo, é obrigatório o uso do certificado SSL para que seja possível autorizar compras com o cartão de crédito).

Afinal, o HTTPS realmente garante nossa segurança ao navegar pela web?

Definitivamente, protocolo HTTPS é considerado mais seguro porque ele faz uma criptografia forte dos dados trafegados ente clientes e servidores. Por isso, podemos concluir que o protocolo HTTPS de fato representa segurança. Porém, tal segurança se aplica somente ao âmbito da conexão e da comunicação entre clientes e servidores.

Uma conexão segura não significa necessariamente um site seguro: existem muitos outros tipos de brechas que podem ser exploradas em aplicações web que não envolvem necessariamente aspectos relacionados à conexão.

O que é CORS e como resolver os principias erros

O CORS (Cross-origin Resource Sharing) é um mecanismo utilizado pelos navegadores para compartilhar recursos entre diferentes origens. O CORS é uma especificação do W3C e faz uso de headers do HTTP para informar aos navegadores se determinado recurso pode ser ou não acessado.

Para compreender melhor, imagine que você está desenvolvendo uma aplicação web que consiste em uma SPA e uma API. Tudo ocorre sem problemas no seu ambiente local, mas ao fazer o deploy em produção você se depara com isso:

Erro de CORS

Isso acontece devido a um mecanismo de segurança presentes nos navegadores chamado de same-origin policy. Ele é usado para limitar como um documento ou script de uma origem pode interagir com recursos de outra origem.

HTTP - Fundamentos
Curso de HTTP - Fundamentos
CONHEÇA O CURSO

Entenda como origem a combinação entre o protocolo (http ou https), o host (painel.treinaweb.com.br) e a porta (80 ou 443, podendo ser omitida) de um determinado endereço (http://painel.treinaweb.com.br/). Se a origem de duas URLs forem idênticas, a interação entre esses recursos pode acontecer sem problema.

Por exemplo, considere a seguinte URL: http://painel.treinaweb.com.br/perfil/. Alguns exemplos de URLs com same-origin considerando a origem são http://painel.treinaweb.com.br/ e http://painel.treinaweb.com.br/cursos/. Nesses casos a única alteração está no path, com o início da URL igual.

Agora, as seguintes URLs seriam bloqueadas: https://painel.treinaweb.com.br/perfil/, http://painel.treinaweb.com.br:81/perfil/index.html, http://www.treinaweb.com.br/. No primeiro caso, o protocolo é diferente (https), no segundo caso temos outra porta e, por fim, o subdomínio do host é diferente.

Em todos esses casos você está sujeito a uma requisição controlada por CORS:

Conceitos de CORS

Possíveis erros de CORS

Como a utilização e compartilhamento de recursos de origens diferentes é algo bastante comum na internet, nem tudo que o navegador precisa carregar está sujeito ao same-origin policy. Sua página está sujeita a algum tipo de problema de CORS em requisições como:

Os casos mais comuns são com as requisições javascript que utilizam XMLHttpRequest ou Fetch APIs. Para esses casos vamos entender como o CORS funciona e como podemos solucionar corretamente esse problema.

JavaScript Avançado
Curso de JavaScript Avançado
CONHEÇA O CURSO

Ciclo de uma requisição com CORS

Ao enviar uma requisição para uma origem diferente, o navegador utiliza de um header específico enviado pelo servidor chamado Access-Control-Allow-Origin. A partir desse e mais alguns headers o navegador determina se aquele recurso será carregado ou não.

Em alguns tipos de requisições, é necessário enviar uma requisição preliminar chamada de preflighted request. O preflighted request utiliza o método OPTIONS do HTTP informando o método e domínio que será invocado para assim garantir que a requisição seguinte pode ser realizada.

Temos abaixo um diagrama que mostra como funciona uma requisição que precisa enviar uma chamada de preflight:

Fluxo de preflight request

Como resolver problemas de CORS

Quando encontramos um erro de CORS, é importante verificar qual requisição esta causando esse problema diretamente no console do seu navegador. Geralmente o problema é causado pela ausência de headers no lado do servidor.

Para corrigir esse problema, garanta que o servidor está enviando os seguintes headers na sua resposta:

Access-Control-Allow-Origin: https://perfil.treinaweb.com.br
Access-Control-Allow-Methods: POST, GET
Access-Control-Allow-Headers: *
Access-Control-Max-Age: 86400

Nesse exemplo, estamos permitindo que a origem https://perfil.treinaweb.com.br acesse os recursos daquele servidor, sendo possível o uso dos métodos HTTP GET e POST, juntamente com qualquer header adicional. Para os casos de preflight request, temos também o header Access-Control-Max-Age que funciona como um cache, em segundos, para essa request.

Tenha uma atenção especial ao header Access-Control-Allow-Origin. Você pode utilizar * como sua origin ou até em partes dela (https://*.treinaweb.com.br por exemplo, para incluir todos os subdomínios da TreinaWeb), mas tente sempre limitar para origens conhecidas da sua aplicação, evitando assim que origens desconhecidas acessem seus servidores.

Como enviar esses headers vai variar dependendo da linguagem ou servidor da sua aplicação. Como por exemplo, com express você pode definir os headers necessários usando um middleware de CORS:

var express = require('express')
var cors = require('cors')
var app = express()

app.use(cors())

app.get('/products/:id', function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for all origins!'})
})

app.listen(80, function () {
  console.log('CORS-enabled web server listening on port 80')
})

Caso você não tenha acesso ao código da sua aplicação, você pode configurar seu servidor web, como o Apache, para retornar esses headers:

Header set Access-Control-Allow-Origin "*"

Em outros casos, pode ser configurar o serviço que você está consumindo, como o S3 da Amazon. Esses serviços podem ser configuráveis com regras específicas para atender esses casos, porém isso varia de serviço a serviço.

Conclusão

Nesse artigo conhecemos o que significa de fato o CORS e como podemos resolver esses tipos de problemas. Existem algumas outras configurações que podem ser feitas para implementar o CORS nas suas aplicações, como o suporte a requests com credentials que não abordamos aqui.

Para saber mais, temos uma excelente referência da Mozilla que explica em detalhes como funciona o CORS.

Gerando certificados SSL gratuitos com Certbot

Vimos anteriormente como automatizar a geração de certificados SSL locais para ambientes de desenvolvimento, mas e quando precisamos de um certificado para um servidor de produção? Não podemos utilizar um certificado local auto-assinado nesse caso, e tradicionalmente para gerar um certificado SSL precisamos pagar por isso.

Entretanto, existe algumas alternativas para gerar um certificado SSL válido para seus ambientes fora do ambiente local. Uma dessas formas é com o Certbot. Vamos conhecer nesse artigo o Certbot, como ele funciona e como podemos configurá-lo em um dos nossos servidores.

O que o Certbot faz

Acessar um site que tenha HTTPS é quase um pré requisito hoje em dia. Além de ser recomendável pelos principais navegadores, acessar um site com HTTPS te dá mais segurança e até ajuda no rankeamento do seu site nos resultados de busca do Google. Para isso é preciso ter um certificado SSL emitido por uma Autoridade Certificadora (Certificate Authority) que reconhece a sua titularidade para determinado domínio. Para uma introdução sobre SSL, leia mais no artigo O que é certificado SSL.

Para gerar um certificado SSL válido é preciso vários passos, como entrar em contato com uma Autoridade Certificadora, gerar a chave privada que vai ser utilizada para assinar seu certificado e enviar seu certificado para a Autoridade Certificadora, validar que você é o responsável pelo domínio que deseja utilizar HTTPS, aguardar a resposta da Autoridade Certificadora e configurar seus servidores. Tudo isso precisa ser repetido anualmente ou a cada três anos, pois o certificado SSL tem um prazo de validade, e geralmente existe um custo envolvido para a emissão desse certificado.

Esse processo pode ser automatizado, e o melhor, realizado de forma gratuita, ao utilizar o Certbot. O Certbot é um utilitário em linha de comando mantida pela Eletronic Frontier Fountation (EFF), uma organização sem fins lucrativos que luta pela privacidade online e desenvolve tecnologias para melhorar a segurança na internet.

Junto com Let’s Encrypt, o Certbot faz parte de uma iniciativa da EFF que tem como objetivo encriptar a internet como um todo. Desde o lançamento do Let’s Encrypt e do Certbot (que chegou na sua versão 1.0 recentemente), o percentual do tráfego web que é encriptado saiu de 40% para 77%, segundo dados da EFF.

Com o Certbot é possível gerar certificados emitidos pelo Let’s Encrypt como Autoridade Certificadora, gerar e configurar esse certificado em seu servidor web e renovar automaticamente esse certificado, tudo isso de forma gratuita. Para isso você só precisa ter acesso SSH ao seu servidor e acesso ao sudo. Caso esteja utilizando uma hospedagem talvez você não tenha acesso ao SSH dos servidores, porém algumas hospedagens já suportam a geração de certificados através dos seus painéis.

Vamos acompanhar como gerar esse certificado utilizando um servidor Ubuntu 18.04 LTS com Ngnix.

Como instalar o Certbot no Ubuntu com Nginx

Para efetuar a instalação do Certbot, é preciso que nosso servidor Web já esteja configurado com nosso domínio e esteja rodando com HTTP. O Certbot se encarregará de configurar um desafio com HTTP para validar que você é responsável por aquele domínio. Caso isso não seja possível, existe a opção de efetuar um desafio incluindo um registro TXT no seu domínio, porém esse processo leva mais tempo.

Site sem HTTPS

Ao selecionar sua distribuição e servidor web, você pode consultar as instruções para instalação. No Ubuntu, vamos adicionar o repositório do apt-get do Cerbot e iniciar sua instalação:

sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository universe
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update

sudo apt install certbot python-certbot-nginx

No último comando, temos a variação de um script python com a variação de web server utilizado. Por exemplo, caso esteja utilizando o Apache, você instalaria python-certbot-apache

O próximo passo é executar o certbot com o argumento do servidor web que você irá configurar:

sudo certbot --nginx

Caso se sinta mais confortável, você pode escolher fazer a configuração do seu servidor web manualmente, e somente gerar o certificado com a opção certonly:

sudo certbot certonly  --nginx

Será feita algumas perguntas, como qual o domínio a ser configurado, se você deseja redirecionar todo o tráfego para HTTPS automaticamente, entre outros. Será gerado então sua chave privada para esse certificado e o Nginx será configurado de acordo:

Execução do certbot

Com isso temos nosso servidor configurado e respondendo em HTTPS!

Site com HTTPS

O Certbot irá gerar um certificado com validade de apenas três meses, ao contrário dos certificados de um ou três anos geralmente emitidos por outras Autoridades Certificadoras. Entretanto, o certificado do Certbot é gratuito e se renova automaticamente. É possível testar o processo de renovação automática com o comando:

sudo certbot renew --dry-run

Caso você esteja utilizando outra distribuição Linux, na página inicial do Certbot você pode consultar instruções detalhadas de como instalar em diferentes distribuições e servidores web:

Opções de servidores e distribuições suportadas

O que mais o Certbot pode fazer?

Vimos aqui o processo de geração de certificados no caso que temos acesso ao servidor via SSH. Em uma hospedagem compartilhada isso pode não ser possível, porém caso a mesma forneça suporte para utilizar um certificado SSL gerado por você, é possível gerar o certificado somente na sua máquina local e fazer o upload dos certificados necessários pela sua hospedagem.

É possível até gerar um certificado wildcard, que é válido para todos os subdomínios, caso seu domínio esteja em um DNS suportado. O processo para gerar um certificado wildcard é bem próximo ao mostrado anteriormente, alterando somente os plugins utilizados na hora da instalação.

Para outras variações de configuração, confira a documentação do Certbot para instruções mais detalhadas para seu cenário. Muito provavelmente você encontrará o que precisa.

Para que serve o certificado SSL?

O número de pessoas que executam transações sensíveis na internet (como compras online, transações bancárias, etc.) cresce cada vez mais. Porém, com a facilidade que a internet trouxe em geral para a execução destas operações, os cuidados devem ser redobrados. Analisar e verificar os sites onde estas operações são feitas com o intuito de detectar se o site é confiável, real e seguro é algo essencial.

Por isso, aspectos relacionados a segurança em geral em aplicações web merecem uma atenção especial. A sensação de segurança que uma aplicação web passa a seus usuários é algo extremamente importante, pois inspira confiança e credibilidade. Uma aplicação web precisa garantir que é verdadeira e que as informações trocadas estarão criptografadas e seguras. Visando isso, a implementação de um certificado SSL torna-se algo essencial.

O SSL (Secure Socket Layer) é um mecanismo de criptografia com o objetivo de aumentar a segurança na troca de informações entre clientes e servidores, protegendo a integridade e veracidade do conteúdo que trafega na internet. O certificado garante que a informação do navegador chegará de forma segura desde um cliente (como um browser) até o servidor do site. Quando você coloca seu número de cartão de crédito em uma página que utiliza SSL por exemplo, os números serão codificados e embaralhados, dificultando que um invasor ou interceptador consiga ver o número de cartão de crédito informado.

HTTP - Fundamentos
Curso de HTTP - Fundamentos
CONHEÇA O CURSO

Com a utilização do certificado SSL, o endereço do seu site passa de HTTP para HTTPS, indicando que as informações trafegadas entre cliente e servidor ocorrerão através do protocolo SSL/TLS e que as informações serão criptografadas. Além disso, os browsers modernos passam a exibir o desenho de um cadeado antes da URL, fazendo com que o usuário saiba que a aplicação web é segura.

O HTTPS (sigla para Hyper Text Transfer Protocol Secure ou Protocolo de Transferência de Hipertexto Seguro) é uma derivação do protocolo HTTP com uma camada SSL/TLS adicional implementada, o que adiciona mais segurança ao HTTP. Como o HTTPS utiliza criptografia, as chances de um intruso interceptar as mensagens trocadas entre cliente e servidor e obter acesso ao conteúdo destas mensagens reduz-se consideravelmente, pois as mensagens passam a ser criptografadas através de certificados digitais. Quando falamos sobre aplicações web, essa criptografia é essencial: através do tradicional HTTP, as mensagens são trafegadas como texto puro, ou seja: caso um interceptador capture mensagens HTTP, este terá total acesso a seu conteúdo sem maiores dores de cabeça. Com o HTTPS e sua criptografia inerente, esse risco é drasticamente reduzido.

Além de deixar o seu site mais seguro e confiável, a utilização do certificado SSL traz um outro benefício: a otimização do SEO. São diversos fatores que influenciam o ranqueamento dos sites no Google, sendo que um destes fatores é justamente a utilização de SSL. Como o Google considera o certificado SSL um benefício importante para os usuários, ele prioriza isso ao selecionar os sites que aparecem na busca, melhorando o posicionamento do seu site.

Como ele funciona?

O ciclo de uma transmissão HTTPS começa com um certificado digital. Um certificado digital é como se fosse uma espécie de RG eletrônico, identificando a sua aplicação como sendo uma aplicação confiável e verdadeira. Certificados digitais devem ser obtidos através de entidades certificadoras (ou CAsCertification Authorities), pois somente estas têm as permissões necessárias para gerar certificados digitais válidos. É um processo muito parecido com o RG humano propriamente dito… Um RG não pode ser emitido em qualquer lugar: ele deve ser solicitado somente em locais autorizados a lidarem com a emissão de RGs e que tenham acesso aos sistemas estaduais e nacionais de identificação. É o mesmo cenário com certificados digitais, já que estes irão identificar sua aplicação dentro de toda a web. Algumas entidades certificadoras são Verisign, GeoTrust, Comodo e Amazon. O serviço de geração de um certificado é geralmente pago e deve ser feito peridiodicamente, pois os certificados possuem uma data de expiração. Também existem serviços que emitem certificados de maneira gratuita, como o Let’s Encrypt.

Um certificado é composto basicamente por duas partes: uma chave pública e uma chave privada que são geradas randomicamente pela entidade certificadora. A chave pública é utilizada para verificar os clientes que realizam as requisições, enquanto a chave privada é utilizada para a realização do processo de criptografia.

Quando você se conecta a um servidor que utilize HTTPS/SSL para a transferência de informações, o servidor irá responder inicialmente com a chave pública e o certificado associado à aplicação que está sendo acessada. Cabe ao cliente (como um browser), ao receber esta chave, verificar alguns pontos:

  • Se a chave pública não está expirada (o que ocorre quando o certificado já se encontra expirado);
  • Se a chave pública pertence realmente à aplicação que está sendo acessada;
  • Se o cliente consegue descriptografar a assinatura digital do certificado enviado, o que significa que aquela chave pública e aquele certificado são válidos.

Quando um destes pontos de verificação falha, o cliente (como um browser) aborta a conexão e mostra uma mensagem de alerta para o usuário parecida com a tela abaixo.

Caso todas as verificações ocorram com sucesso, o browser entende que a comunicação está sendo feita com um servidor confiável.

Quando o cliente detecta que a conexão é confiável, o cliente cria uma nova chave, chamada de chave de sessão ou session key. Com a chave de sessão criada, o cliente envia esta chave de volta ao servidor, porém, criptografada com a chave pública validada nos passos anteriores.

Quando o servidor recebe a chave de sessão do cliente, ele utiliza a chave privada (que nunca é trafegada entre as requisições) para tentar obter a chave de sessão informada pelo browser. Um conteúdo criptografado com a chave pública só pode ser descriptografado com a chave privada, o que garante a autenticidade e legitimidade das informações que são trafegadas criptografadas com a chave pública. Caso o servidor consiga realizar este processo, é enviado de volta ao cliente uma resposta de que “está tudo OK”, também chamada de ACK (acknowledgement ou reconhecimento). Esse processo todo é chamado de handshake, pois agora somente o cliente e o servidor têm conhecimento das chaves públicas e de sessão que foram trocadas. É como se o cliente e o servidor tivessem se identificado um com o outro e, após existir a confiança entre os dois, ambos apertassem as mãos e disessem: “sei que você é você mesmo de fato e, por isso, confio nas informações que vamos trafegar entre nós”.

A partir deste momento, o servidor passa a responder as informações de volta ao cliente criptografando-as com a chave de sessão que somente o cliente e o servidor têm conhecimento. O cliente passa a utilizar a chave de sessão para descriptografar as informações enviadas pelo servidor. Quando o cliente precisa enviar informações para o servidor, este utiliza também a chave de sessão para criptografar o conteúdo, enquanto o servidor utiliza a mesma chave (que somente este cliente e o servidor possuem conhecimento) para descriptografar o conteúdo.

Veja que o processo de confidencialidade é bem forte neste processo: se algum interceptador interceptar estas mensagens, este não terá a chave de sessão vinculada ao cliente para descriptografar as mensagens. Ele também não conseguirá obter esta chave de sessão, mesmo que ele tenha acesso à chave pública do certificado: não se esqueça que o conteúdo criptografado com a chave pública só pode ser descriptografado com a chave privada. A única maneira de um invasor conseguir descriptografar o conteúdo é se este, de alguma maneira, tiver acesso à chave privada do certificado do servidor ou à chave de sessão do cliente.

Um ponto interessante é que esse processo de criptografia que é utilizado no HTTPS é chamado por muitos de criptografia assimétrica, já que existem duas chaves de criptografia utilizadas durante o processo: uma estática, mas que fica escondida no cliente (no caso da chave privada) e no cliente (no caso da chave de sessão); e uma chave pública, cujo conteúdo só pode ser descriptografado justamente com a chave privada. Veja que esse processo é diferente da criptografia “tradicional”, que também é dita como criptografia simétrica, onde só existe uma chave estática para a realização do processo de criptografia e descriptografia.

HTTP/2: o que você deve saber?

O protocolo HTTP é um protocolo importante, já que ele é a base da internet e das aplicações web na maneira que conhecemos hoje. E, como a maioria das tecnologias que são extensamente utilizadas, ele evoluiu. Sendo assim, temos uma nova versão do HTTP: o HTTP/2. Antes de tudo, caso não conheça o protocolo HTTP, sugerimos a leitura do artigo “O que é HTTP, Request, GET, POST, Response, 200, 404?”., onde os princípios básicos do protocolo HTTP são abordados. Mas, de forma bem resumida, o HTTP é um protocolo de transferência de arquivos e dados, que vão de um servidor até o cliente (navegador) que solicita estes arquivos e dados.

HTTP - Fundamentos
Curso de HTTP - Fundamentos
CONHEÇA O CURSO

O protocolo HTTP/2

Já de início, devemos ressaltar que o HTTP/2 não muda a semântica do HTTP/1: tudo continua da mesma forma que já conhecemos, com seus verbos e status HTTP. O HTTP/2 foi desenvolvido para resolver alguns problemas que existiam na versão 1.1, principalmente com relação à performance. A maior parte das mudanças dizem respeito à forma que os recursos são transportados entre o cliente e o servidor, tornando esse processo muito mais performático, mesmo em cenários com múltiplas requisições simultâneas.

O HTTP/2 implementa um formato de entrega mais eficiente, acelerando o carregamento das páginas e elementos de uma aplicação web. Este é a principal vantagem que temos na utilização do HTTP/2. Mas ainda existem outras vantagens interessantes, que serão abordadas a seguir.

Multiplexação de mensagens

No HTTP/1, uma conexão é utilizada para baixar um único arquivo, tornando o processo de download de conteúdo algo sequencial. Ou seja: os recursos serão baixados uns atrás dos outros, até que essa “fila de downloads” acabe. Com isso, se um arquivo é muito grande e o servidor ficar lento no meio do processo de download, a página pode acabar passando por um congelamento. Mas o HTTP/2 implementou a multiplexação de mensagens. Com a multiplexação, o navegador não precisa mais ficar esperando receber um recurso para poder requisitar os recursos seguintes. Com o HTTP/2, o navegador pode solicitar e ter a resposta de vários recursos de forma paralela através de apenas uma conexão.

Server Push

Outra funcionalidade bem interessante é o Server Push. Com o HTTP/1.1 (versão anterior do protocolo), o navegador abria uma conexão para baixar cada item da página, se estivermos considerando a carga de uma página web: era uma conexão para baixar o CSS, outra conexão para baixar o JavaScript, e assim por diante, até que todo conteúdo vinculado à página fosse baixado completamente. Se estivermos falando de uma aplicação web que precisa de muitos recursos para ser renderizada, esse processo pode ser um pouco demorado… Já no HTTP/2, o servidor pode enviar recursos ao cache do navegador antes mesmo que o cliente o solicite! Com isso, é possível disponibilizar recursos (como arquivos JavaScript, CSS, imagens e outros recursos comumente utilizados por uma aplicação web) logo durante a interpretação do HTML.

Compressão de cabeçalho (HPACK)

Toda transferência contém um cabeçalho com diversas informações que descreve o recurso que está sendo transferido. Para reduzir a carga e melhorar o desempenho, o HTTP/2 utiliza um algoritmo chamado HPACK para compressão desse cabeçalho, gerando requisições mais leves e, consequentemente, fazendo com que os recursos sejam carregados mais rapidamente.

Priorização de requisições

O HTTP/1.1 tem dificuldade nesse quesito de priorizar requisições. Uma página web é composta por vários elementos. Estes elementos podem ter prioridades diferentes de carregamento no que diz respeito à carga de um recurso. Por exemplo: se estivermos falando de uma página web, não faz sentido que o CSS seja carregado antes de que o HTML esteja disponível.
O HTTP/2 soluciona este problema, já que é possível definir prioridades para os recursos a serem carregados por uma página web, por exemplo. Isso nos possibilitaria instruir o browser a baixar um arquivo CSS que poderia causar bloqueios no processo de renderização da página, caso fosse baixado tardiamente, com uma ordem de prioridade superior aos demais recursos.Esse tipo de priorização não existe no protocolo HTTP/1.1.

Obrigação na utilização de SSL (HTTPS)

Para adotar o HTTP/2, o uso de SSL se torna obrigatório. Isso em termos práticos quer dizer que todo conteúdo trafegado em conexões HTTP/2 estará criptografado com certificados SSL (HTTPS).

O nível atual de adoção do protocolo HTTP/2

Os principais navegadores (como o Chrome, Firefox, Safari e Edge) já oferecem suporte ao HTTP/2. É necessário que os clientes também suportem o HTTP/2 para que seja possível utilizá-lo. Alguns servidores famosos (como o Apache, Tomcat e Nginx) também já suportam o HTTP 2. Caso queira ver uma lista completa, você pode acessar por este link no GitHub.

Para que você perceba a diferença do HTTP/1.1 e do HTTP/2 na prática, você pode abrir o HTTP 2 – Technology Demo. Lá, existe um exemplo de um download de uma foto composta por 200 pequenas imagens através do protocolo HTTP/1.1 e através do protocolo HTTP/2. Nesse cenário, a melhor performance do protocolo HTTP/2 é explícita.

Principais métodos para obtenção de parâmetros da Request no Laravel

Nesse artigo vamos ver como obter os dados enviados pelo usuário no Laravel. Na verdade, quando falamos em pegar dados enviados pelo usuário, seja via formulário ou diretamente na URL, estamos falando da Request. Caso não saiba o que é Request temos esse artigo que fala sobre alguns conceitos HTTP.

O Laravel possui uma classe específica para trabalhar com os dados enviados na requisição. Essa classe tem o nome de Request e fica no namespace \Illuminate\Http. Ela possui uma série de métodos que facilitam obtenção das informações enviadas pelo cliente.

PHP Intermediário
Curso de PHP Intermediário
CONHEÇA O CURSO

Como podemos utilizar a classe Request

Geralmente o local onde mais usamos os dados enviados na requisição é o Controller. No Laravel, podemos injetar instâncias diretamente nos métodos do controller, isso nos permite usar facilmente a instância da classe Request.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ProductController extends Controller
{
    public function store(Request $request)
    {
        //Usamos a instância para chamar os métodos da requisição
        $request->...();
    }
}

Obtendo dados enviados via URL

O modo mais simples de enviar informações do usuário para o servidor através da requisição é a URL. Usando um padrão específico podemos passar dados no formato chave valor, veja a URL abaixo:

http://servidor.test/meurecurso?escola=Treinaweb&curso=Laravel

Através dela estamos passando os parâmetros escola e curso que possuem respectivamente os valores TreinaWeb e Laravel.

Para obter todos os dados passados na URL usamos o método query sem passar nenhum parâmetro $request-&gt;query(). O Laravel pega todos os parâmetros e retorna em forma de array:

array:2 [
  "escola" => "Treinaweb"
  "curso" => "Laravel"
]

O método query pode ser usado para obter apenas um valor, basta passar o nome da chave no primeiro argumento. Caso a chave não esteja declarada na URL ainda é possível definir um valor padrão no segundo argumento.

$request->query("escola");
$request->query("escola", "Valor padrao");

Montando o formulário de exemplo

Os dados enviados via POST estão localizados no corpo da requisição. O Laravel possui alguns métodos que nos permitem obter essas informações para serem usadas na nossa aplicação.

Para conseguirmos enviar informações via POST precisamos criar um formulário que será submetido para uma rota qualquer da nossa aplicação. Vamos usar como base o seguinte formulário:

<form action="http://servidor.test/meurecurso" method="POST">
    {{ csrf_field() }}
    Nome <input type="text" name="name" value="Elton"> <br>
    Idade <input type="text" name="age" value="27"> <br>
    Email<input type="text" name="email" value="elton.fonseca@treinaweb.com.br"> <br>
    <input type="submit" value="Enviar">
</form>

OBS: o helper csrf_field retorna um input do tipo hidden com o token que confirma que o formulário está sendo realmente enviado pela nossa aplicação.

Obtendo dados enviados via POST

O primeiro método que vamos falar é o all() ele retorna todos os dados em formato de array:

array:3 [
  "name" => "Elton"
  "age" => "27"
  "email" => "elton.fonseca@treinaweb.com.br"
]

Outro método que podemos usar é o input. Ele retorna um único valor e podemos definir um valor padrão como segundo argumento, caso a chave não seja encontrada:

$request->input('name');
$request->input('name', 'Nome padrão');

Temos também os métodos only que busca apenas os parâmetros especificados nele e o método except que trás todos parâmetros, exceto os especificados nele. Podemos passar uma lista de argumentos ou um array:

$request->only('name', 'email');
$request->only(['name', 'email']);
$request->except('age');
$request->except(['age']);

Todas as chamadas acima retornam a mesma informação:

array:2 [
  "name" => "Elton"
  "email" => "elton.fonseca@treinaweb.com.br"
]

Uma observação importante! Todos os métodos que vimos nesse tópico all(), input(), only() e except() pegam valores passados via POST e também via GET na URL, dando preferência para os parâmetros POST quando eles possuem o mesmo nome. Enquanto o query, que vimos no tópico anterior, pega apenas os parâmetros passados via GET.

Laravel - Framework PHP (Parte 1/3)
Curso de Laravel - Framework PHP (Parte 1/3)
CONHEÇA O CURSO

Propriedade dinâmica

O Laravel cria propriedades dinamicamente para os parâmetros enviados na requisição, essas propriedades facilitam o acesso aos dados e torna o código mais limpo.

$request->name;  //Treinaweb
$request->age;   //27
$request->email; //elton.fonseca@treinaweb.com.br

É possível obter dinamicamente os parâmetros enviados via GET e POST.

Helper request

Existem algumas situações onde precisamos usar os dados da requisição em locais onde não temos fácil acesso a instância da requisição, nesses casos podemos usar o helper request. Quando chamamos o helper sem passar nenhum argumento ele retorna uma instância da classe request, a partir dela podemos chamar qualquer método da Request:

request()->all();
request()->input("name");
request()->only("email");
//...

Ainda é possível pegar os dados do parâmetro passando o nome do argumento e o valor padrão, para caso o parâmetro não seja encontrado:

request("name", "Nome padrão");

Verificando o parâmetro

Outra situação comum é precisamos verificar se um parâmetro foi passado na requisição. Para isso usamos o método has(). Ele retorna verdadeiro independente do valor passado, mesmo que o valor seja vazio:

if ($request->has('name')) {
    //
}

Caso precise verificar se o parâmetro foi passado na requisição e não é vazio, podemos usar o método filled():

if ($request->filled('name')) {
    //
}

Obter arquivo e realizar upload

O Laravel possui um método especial chamado file para obter os arquivos. Também é possível usar as propriedades dinâmicas:

$request->file('image');
$request->image;

Esse método retorna uma instância da classe Illuminate\Http\UploadedFile, ela já possui todos os recursos necessários para salvar o arquivo de maneira simples. Podemos simplesmente chamar o método store para salvar o arquivo:

$request->file('image')->store('local');

Conclusão

Nesse post nós vimos os principais métodos para obtenção de parâmetros enviados pelo usuário através da requisição. Além desses dados a requisição ainda possui diversas outras informações que são enviadas pelo cliente da nossa aplicação. A documentação do Laravel possui vários exemplos práticos de como obter esses dados.

Desenvolvedor Laravel Full-Stack
Formação: Desenvolvedor Laravel Full-Stack
Nesta formação você aprenderá desenvolver aplicações PHP usando o framework Laravel com maestria. Ao final desta formação, você terá condições de trabalhar em grandes aplicações web ou APIs integradas com diversos serviços, tudo isso utilizando as melhores práticas do mercado.
CONHEÇA A FORMAÇÃO

O que é HTTP, Request, GET, POST, Response, 200, 404?

Aprenda nesse post de forma simples e direta os principais conceitos HTTP que sempre teve dúvida, porém nunca teve coragem de perguntar.

Nosso objetivo nesse post não é entrar 100% na parte técnica do protocolo HTTP, mas sim apresentar uma visão prática dele. Caso tenha interesse em se aprofundar aconselho dar uma olhada no nosso curso específico:

HTTP - Fundamentos
Curso de HTTP - Fundamentos
CONHEÇA O CURSO

Antes de falar sobre conceitos que fazem parte do HTTP, precisamos entender o que é o HTTP em si.

O que é HTTP

O HTTP é um protocolo de comunicação. Através dele o cliente e o servidor conseguem se comunicar, seguindo um conjunto de regras bem definidas (por isso chamamos de protocolo).
Por exemplo, se estivermos falando de uma aplicação web, o cliente é o navegador, ele envia um pedido para o servidor web usando o protocolo HTTP, com base nesse pedido, se tudo estiver correto, o servidor responde também usando o mesmo protocolo o conteúdo solicitado.

O que é Request

A Request ou requisição traduzindo diretamente para português, é o pedido que um cliente realiza a nosso servidor. Esse pedido contém uma série de dados que são usados para descrever exatamente o que o cliente precisa. Vamos pensar que um cliente precisa cadastrar um novo produto, ele deve passar todos os dados necessários para o cadastro acontecer de maneira correta, inclusive os dados que foram digitados pelo usuário em um formulário, no caso de uma aplicação web.
No navegador toda vez que trocamos de página ou apertamos enter na barra de endereço uma nova request é feita. Independente se estamos apenas pedindo a exibição de uma página, cadastrando um novo recurso, atualizando ou excluindo.

O que é GET e POST?

Tanto GET como POST na verdade são métodos HTTP. Eles indicam para o servidor qual a ação que o cliente deseja realizar. Quando realizamos uma requisição obrigatoriamente precisamos informar um método.

  • GET – é usado quando o cliente deseja obter recursos do servidor
  • POST – é usado quando o cliente deseja enviar dados para processamento ao servidor, como os dados de um formulário, por exemplo.

Existem outros métodos HTTP. Os dois métodos citados acima são os mais usados, principalmente em aplicações web. Quando o usuário digita um endereço e aperta enter na barra de endereço do navegador, ele realiza uma requisição do tipo GET. Já quando preenchemos um formulário e clicamos em enviar geralmente o método usado é o POST.

O que é Response

Vimos que o cliente envia uma Request (requisição) ao servidor. Essa requisição possui todas as informações acerca do que o cliente espera receber de volta. O servidor web ao receber essas informações precisa enviar uma resposta ao cliente, nesse ponto entra a Response.
A Response (resposta) nada mais é do que a resposta que o servidor envia ao cliente. Essa resposta pode conter os dados que realmente o cliente esperava receber ou uma resposta informando que alguma coisa deu errado.

O que é 200, 404, 301 e outros números?

Esses números são os chamados códigos HTTP. Quando o cliente faz uma requisição ele espera uma resposta. O servidor pode realmente responder o que o cliente esperava ou devolver outra informação, justamente nesse ponto entram os códigos HTTP. O servidor utiliza um código desse na resposta para indicar o que aconteceu.

Os códigos estão entre 100 e 500, sendo que cada centena indica uma categoria:
– 1xx – Informativos
– 2xx – Indicativos de sucesso
– 3xx – Redirecionamentos
– 4xx – Erros do cliente na hora de fazer a solicitação
– 5xx – Erros no lado do servidor

Dentro de cada centena temos os códigos específicos, por exemplo:
– 200 – Tudo ocorreu corretamente
– 301 – Indica redirecionamento permanente
– 401 – Não autorizado
– 404 – O recurso solicitado não foi encontrado no servidor

Existem vários sites que especificam todos os códigos HTTP. Esse usa cachorrinhos como exemplo , mas se você gosta mais dos gatinhos também existe.

Resumo

O HTTP é o protocolo que define as regras para a comunicação entre o cliente o servidor. No fluxo básico o cliente realiza uma requisição para o servidor, nessa requisição é enviada além de várias outras informações um método que indica a ação que ele deseja. O servidor devolve uma resposta, nessa resposta, além de outras informações, existe um código que indica ao cliente o que aconteceu. Caso você queira se aprofundar no assunto também abordamos no blog sobre o protocolo HTTP/2, que é a evolução do HTTP.

Desenvolvedor Laravel Full-Stack
Formação: Desenvolvedor Laravel Full-Stack
Nesta formação você aprenderá desenvolver aplicações PHP usando o framework Laravel com maestria. Ao final desta formação, você terá condições de trabalhar em grandes aplicações web ou APIs integradas com diversos serviços, tudo isso utilizando as melhores práticas do mercado.
CONHEÇA A FORMAÇÃO

Checklist de segurança para autenticação

Cuidar da segurança é um dos pilares para a sustentação de qualquer aplicação na web. Sem o mínimo não é possível nem mesmo garantir uma razoável disponibilidade.

Nesse artigo eu listo alguns dos tópicos que acredito serem de fundamental importância para a integridade e confidencialidade nos processo de autenticação (com foco em autenticação por cookie). Nas próximas semanas novos artigos correlatos à segurança serão publicados.

1) Use HTTPS em todo lugar;
2) Armazene as senhas com segurança;
3) Não impeça o seu usuário de criar uma senha forte;
4) Não transporte pela rede, sem motivo, os dados sensíveis do seu usuário;
5) Limite as tentativas de login;
6) Deixe-o opcionalmente resetar a senha;
7) Cuide da criação dos Cookies e, após o logout, destrua os identificadores da sessão;

1) Use HTTPS em todo lugar

Há alguns anos era comum os sites apenas forçarem o uso do protocolo HTTPS em áreas críticas e sensíveis como, por exemplo, no checkout, login ou cadastro.

Hoje, não só pela maior acessibilidade em gerar certificados SSL, é uma recomendação e um padrão que os sites rodem completamente sob o protocolo HTTPS. O HTTP caminha para se tornar defasado e os navegadores em breve emitirão warnings (sem exceção) para sites que rodem nele.

Desenvolvedor PHP Pleno
Formação: Desenvolvedor PHP Pleno
Nesta formação você aprenderá aspectos mais avançados da linguagem PHP, indo adiante nas características da linguagem, orientação a objetos, práticas de mercado, além da parte de integração com banco de dados. Ao final, estará apto a desenvolver sistemas usando banco de dados relacionais.
CONHEÇA A FORMAÇÃO

A Mozilla (mantenedora do Firefox) publicou no final de 2015 um post demonstrando intenção e um projeto para depreciar o HTTP.

Se a sua preocupação é o preço que se paga por um certificado SSL, bom, ela não deve mais existir! Meados de 2016 foi lançado o Let’s Encrypt, uma autoridade de certificação completamente gratuita. Ela é mantida por grandes organizações e através de doações. A ideia é tornar a web completamente HTTPS em alguns anos.

Há de se ressaltar, no entanto, que o protocolo HTTPS em si não garantirá que o seu site seja confiável, ele apenas garantirá a confidencialidade da troca de informações. Se você não cuidar dos dados do seu usuário como, por exemplo, se os trafegar no subterrâneo da web sem segurança, se salvar a senha dele em plain text na base, etc, de nada adiantará.

Ah, falando em protocolo HTTP, muito recomendo o nosso curso de introdução ao http. Com ele você terá uma visão geral muito bacana sobre os “bastidores” de como a web funciona. Essencial para qualquer desenvolvedor:

2) Armazene as senhas com segurança

Nunca armazene as senhas dos usuários em “plain text”, use algum moderno hash de password como o bcrypt (mais acessível) ou o Argon2, vencedor da última competição de password hashing. Ele é o que de mais moderno temos para passwords.

Se sua linguagem suportar nativamente (como é o caso do PHP 7.2) a library Libsodium, que é uma das mais recomendadas entre os especialistas de segurança como uma completa toolkit de criptografia e hashing, por agrupar os melhores e mais sofisticados algoritmos (como o Argon2, anteriormente mencionado), use-a. Mesmo se não suportá-la nativamente (na standard library), certamente haverá uma forma de importá-la para o seu projeto.

Não devemos, como desenvolvedores, partindo do pressuposto de que a maioria de nós não é especialista em criptografia, criar as nossas próprias bibliotecas para resolver tais questões. Usemos as criadas, testadas e auditadas por especialistas. Andar sobre um terreno desconhecido pode nos levar à nefastas consequências.

Vale a pena reforçar: Descarte qualquer artigo ou referência que indique algoritmos de hashing como o MD5 e SHA1 para armazenamento de passwords (mesmo que com salt’s). Eles não foram projetados para esse propósito. Além disso, não são seguros, principalmente por serem suscetíveis à ataques de colisão. Uma colisão num algoritmo de hashing é, basicamente, uma mesma saída sendo representada para diferentes entradas (sendo que a premissa deles é, em teoria, uma representação (de saída) única para cada entrada).

Leitura recomendada: Password Storage Cheat Sheet.

Se você usa um Web Framework (Rails, Laravel etc), é bem possível que ele já abstraia uma camada de autenticação usando as melhores práticas. Mas é sempre bom tirar um tempo e consultar a documentação.

3) Não impeça o seu usuário de criar uma senha forte

É extremamente comum sites que possuem regras bastante estranhas (quiçá equivocadas) para a definição de passwords. Eu passo bastante por esse tipo de situação pois eu uso um password manager e crio senhas únicas de mais de 32 caracteres para cada serviço, no entanto, não é todo site que as aceita.

Algumas das regras que considero equivocadas:

Exigir que o password tenha apenas letras e números (sem caracteres especiais);

Se o seu site usa um hash de password como comentado anteriormente (e ele deveria usar um), ter a senha com caracteres especiais, números, letras etc, nunca vai ser um problema. Muito pelo contrário, se puder, incentive o seu usuário a criar senhas que usem toda essa pluralidade (mas, sem obrigá-lo, ademais, a segurança também é uma responsabilidade que precisa partir do usuário).

Delimitar o tamanho do password;

Alguns sites delimitam um máximo de 14 ~ 16 caracteres para a senha. Isso não faz sentido. Limitar um mínimo, até faz e, nesse caso, é você prezando (ou ao menos tentando) pela qualidade da senha do seu usuário. Por exemplo: “A senha deve ter no mínimo 6 caracteres”.

Se o seu site lida com informações sensíveis e críticas, você até pode ter um sistema que aceite senhas pequenas, desde que você implemente, por exemplo, autenticação multifator (multi-factor authentication). Um exemplo são os bancos, a senha web é pequena, no entanto, não é possível acessar a interface da conta sem confirmar o token que é gerado por aplicativo ou enviado por SMS.

A estratégia e o critério aqui vai depender do nicho do seu negócio, da criticidade das informações transacionadas por ele.

Como regra geral: Se o seu usuário quer cadastrar uma senha forte, não o impeça disso. É frustrante.

4) Não transporte pela rede, sem motivo, os dados sensíveis do seu usuário

Eu já passei, mais de uma vez, pela situação de o site me enviar no e-mail a senha que eu usei no cadastro. Isso é uma das piores coisas que você pode fazer ao confirmar um cadastro.

A senha do seu usuário é um dado sensível, extremamente sensível, é sagrada. Ela não pode e nem deve ser exposta. Tanto que, ao gravá-la na base de dados, temos o cuidado de usar um hash de password.

Infelizmente a maioria dos usuários ainda não tem a cultura de usar um password manager e, naturalmente, com uma web tão saturada, tantos serviços, tantas redes sociais, as senhas são normalmente reutilizadas em dezenas de serviços. É bem que possível que aquela senha que foi enviada no e-mail seja a porta de entrada para dezenas de outros serviços que o seu usuário utiliza.

5) Limite as tentativas de login

Logins são alvos de bots em ataques de força bruta. Criar um mecanismo para limitar um número de vezes que um determinado IP pode tentar logar (ou IP e username) é uma boa alternativa.

Alguns frameworks já possuem tal implementação, bastando apenas utilizá-la, normalmente é um middleware que precisa ser atrelado à rota de login. Cada tentativa de acesso é salva em cache (de preferência cache em memória) e se ultrapassar o limite estabelecido (por exemplo, 6 tentativas), o usuário fica bloqueado de tentar novamente por um ou dois minutos, por exemplo (a depender da sua escolha).

Se o seu login estiver sob forte ameaça desse ataque, uma opção paliativa é usar um captcha como o reCaptcha do Google, ao menos que temporariamente. O problema dessa opção é que prejudica muito a usabilidade do usuário mas, dependendo da situação, pode ser uma grande aliada.

Se o ataque de força bruta estiver generalizado e vindo de muitos diferentes IP’s, talvez uma boa opção seja utilizar um serviço de segurança que trabalhe como um firewall ainda no DNS mitigando-os (como a Cloudflare).

6) Deixe-o opcionalmente resetar a senha

Essa opção é excelente para a usabilidade do usuário, imagina se ele tivesse que entrar em contato sempre que precisasse alterar a senha? Mesmo que essa não seja uma prática rotineira, seria contra-produtivo.

Mas há de se ressaltar que esse é um processo razoavelmente crítico e que costuma sofrer ataques, portanto, precisa ser bem modelado. Abaixo vou listar o que não deve ser feito ao resetar uma senha e algumas recomendações do que pode / deve ser feito.

O que não deve ser feito:

  • Não envie a nova senha no e-mail;
  • Não envie a senha antiga no e-mail;

Pra começo de conversa, se você ao menos tem o “poder” de conhecer a senha antiga do seu usuário, está errado, pois isso mostra que ela está sendo armazenada em plain text.

O que deve / pode ser feito:

  • Dê opção no seu painel administrativo para o usuário desativar a opção de recuperação de senha.

Pode parecer “estranha” essa hipótese, mas quem usa um password manager pode não ter interesse em ter a função de recuperar senha. Pra ele não faz muito sentido. Tê-la sem que ele vá utilizar, pode vir a ser, no futuro, uma brecha para a segurança da conta. Vamos pensar, hipoteticamente: ele esquece a conta de e-mail logada no computador da empresa onde trabalha. Um usuário a acessa e então pode solicitar a recuperação da senha de algum serviço que ele usa, o e-mail chegará, ele alterará a senha e por consequência, terá o controle da conta.

É verdade que a hipótese acima não aconteceria se houvesse uma verificação adicional como, por exemplo, enviar um token via SMS para o usuário confirmar e só então enviar o e-mail com o link para resetar a senha.

O fluxo padrão de uma recuperação de senha efetiva:

  • Gere um token para recuperação da senha e salve-o no banco de dados;
  • Se uma nova tentativa de recuperar a senha for realizada, remova o token anteriormente criado e gere um novo;
  • Envie o token no e-mail do usuário, em um link, para que ele não precise copiá-lo e depois colá-lo em algum input do site para validação;
  • Após a definição da nova senha, remova o token da base de dados;

Há diferentes estratégias para essa geração e avaliação dos tokens. Existem detalhes conceituais que precisam ser considerados, como: avalio o token diretamente na base de dados ou avalio em constant time usando uma função segura para avaliação de strings? Em constant time é a melhor opção, pois evita timing attack. No PHP temos a função hash_equals() que compara duas strings de forma segura.

O objetivo desse artigo não é adentrar em detalhes de implementação, mas eu deixo aqui uma excelente referência para estudo.

Desenvolvedor Java Web Pleno
Formação: Desenvolvedor Java Web Pleno
A formação Desenvolvedor Java Web nível Pleno da TreinaWeb tem como objetivo a apresentação de tecnologias mais avançadas para o desenvolvimento de aplicações web dentro da plataforma Java. Além de serem abordados frameworks e bibliotecas populares no desenvolvimento web, como o jQuery e o Bootstrap, a formação também dá um foco especial a um dos mais importantes frameworks dentro do ecossistema Java: o Spring, largamente utilizado para criação principalmente de aplicações baseadas na web.
CONHEÇA A FORMAÇÃO

7) Cuide da criação dos Cookies e, após o logout, destrua os identificadores da sessão

Num sistema tradicional de autenticação por cookie, temos essa relação:

A credencial do usuário é validada, um cookie é enviado na resposta da requisição HTTP (e o navegador trata de criá-lo no disco). No lado do servidor, um arquivo que identifica esse Cookie também é criado e é nesse arquivo que alguns dados dos usuários são salvos (id etc), no servidor, isso é o que chamamos de “sessão”. Normalmente é salvo no disco, mas também pode ser salvo em memória (memcached, redis etc). Sempre que o seu usuário fizer logout, essa referência que ficou no servidor (esse arquivo de sessão), precisa ser forçadamente removido.

Segurança:

Sempre crie os seus Cookies configurando-os como “Secure” e “httpOnly”.

Quando criado como “Secure”, ele só roda sob HTTPS. E quando criado como “httpOnly” não é possível resgatá-lo via JavaScript, isso previne que algum ataque XSS bem sucedido roube-o.

Leitura recomendada: httpOnly

Ah, claro, outra boa prática: criptografe o conteúdo dos seus cookies. Se você observar novamente a última imagem, mais especificamente na key “content”, verá que é um conteúdo criptografado. A ideia é não expor facilmente alguma informação sensível.

Novamente, vale reiterar: se você usa um framework importante da sua linguagem, teoricamente ele segue (ou deveria) as melhores práticas acima mencionadas. Mas é bom certificar-se de tais pormenores.

Previna ataques cross-site utilizando SameSite cookies:

SameSite é um atributo relativamente novo disponível para a criação de Cookies. Ele foi colocado como recomendação da IETF no ano passado (em 2016).

Esse atributo é suportado pelo Chrome desde a versão 59. O suporte completo você pode conferir aqui. Ele resolve a maioria dos ataques de CSRF.

Um ótimo case é do Dropbox, a equipe de engenharia deles explica aqui como aplicarem esse novo atributo e o que ele resolve para eles.

Aproveite e também leia: Cross-Site Request Forgery (CSRF) e abordagens para mitigá-lo

Concluindo

Há, certamente, outros tópicos importantes intrinsecamente ou não relacionados à autenticação e que certamente abordarei em outros artigos como, por exemplo, cuidar da validação dos dados recebidos, na camada de acesso ao banco de dados usar queries parametrizadas e assim por diante.

Até a próxima!

REST não é simplesmente retornar JSON: indo além com APIs REST

É até comum, de certa forma, ouvirmos alguém falar que construiu uma API REST porque acabou disponibilizando um endpoint que retorna alguma informação no formato JSON. Mas isso, infelizmente, é um equívoco. Criar uma API REST nada tem a ver com simplesmente retornar algum JSON.

Neste post, vamos discutir sobre os conceitos de REST e JSON e verificar que, apesar de serem conceitos muito íntimos hoje, tecnicamente um não não tem nada a ver com o outro.

HTTP - Fundamentos
Curso de HTTP - Fundamentos
CONHEÇA O CURSO

Mas, afinal de contas, o que é REST?


Hmmm, pelo jeito é algo arquitetural…

REST é um acrônimo para REpresentational State Transfer, ou seja, Transferência de Representação de Estado. O REST é, no final das contas, um estilo arquitetural que podemos utilizar ou não em nossas aplicações.

O conceito do REST foi criado pelo norte-americano Roy Fielding. Roy é também um dos principais responsáveis pela especificação técnica do protocolo HTTP. Sim, esse mesmo protocolo que você está utilizando nesse exato momento para visualizar esta página em nosso blog. A idéia do REST é utilizar de maneira mais eficiente e em sua plenitude as características do protocolo HTTP, principalmente no que diz respeito à semântica do protocolo. O resultado disso ao final das contas é, além da utilização mais “correta” do protocolo, um trânsito de informações mais eficiente e, por consequência, mais rápido.

Mas quais são as características do protocolo HTTP?

O protocolo HTTP, por decorrência de sua arquitetura, possui algumas características bem marcantes:

  • É um protocolo cliente-servidor: o protocolo HTTP se caracteriza por uma conexão feita entre uma máquina cliente e uma máquina servidora. Quando você acessa o nosso blog, por exemplo, você está fechando uma via de comunicação entre a sua máquina com o nosso servidor. É através dessa conexão que seu browser baixa o HTML, o CSS, o JavaScript e as imagens necessárias para renderizar a página solicitada;

  • A comunicação entre o cliente e o servidor é feita através de “mensagens HTTP”: o tráfego de dados entre um cliente e um servidor é feito através de porções de informação chamadas mensagens. Em uma “rodada” de comunicação, nós temos duas mensagens envolvidas: a mensagem enviada pelo cliente solicitando algo, chamada de request; e a resposta do servidor para a solicitação realizada, chamada de response. Estes dois componentes são essenciais para que a comunicação ocorra seguindo o protocolo HTTP e não é possível ter um request sem que depois haja um response e vice-versa;

  • O protocolo HTTP por definição não é “keep alive”: por padrão, uma conexão HTTP só dura até o momento em que o ciclo request-response é concluído. Logo após este ciclo, a conexão é automaticamente encerrada, ou seja: a conexão morre. Caso algum novo conteúdo precise ser trafegado entre o cliente e o servidor, uma nova conexão é aberta. Hoje, até existe maneiras de se modificar esse comportamento utilizando-se algumas flags na requisição (uma destas flags se chama justamente keep-alive), mas é importante destacar que o protocolo originalmente não foi planejado para essa finalidade;

  • O protocolo HTTP é utilizado de maneira assíncrona na maioria dos clientes: requisições HTTP são assíncronas por definição do lado dos clientes. Isso quer dizer que, se você precisa disparar duas requisições para baixar dois conteúdos distintos, o cliente pode disparar essas requisições ao mesmo tempo, sendo que cada uma delas pode ser respondida em um tempo diferente. O protocolo HTTP foi concebido para funcionar desta forma. Inclusive, quando você renderiza uma página, você pode verificar este comportamento observando a aba “Network” do Web Inspector se você utiliza browsers baseados no WebKit/Blink, como o Chrome:

Na figura acima, temos a inspeção do carregamento da página inicial do nosso blog. Cada um dos componentes listados abaixo do gráfico representa um componente que foi solicitado ao servidor, ou seja: houve um ciclo de requisição HTTP para a obtenção de cada um daqueles componentes, sendo que cada ciclo deste foi transmitido dentro de uma conexão própria ao servidor. O gráfico acima mostra o momento que a requisição foi disparada, bem como quanto tempo o servidor demorou para devolver a response correspondente.

Veja que no gráfico acima, podemos notar que o browser dispara várias requisições ao mesmo tempo, sendo que cada uma tem sua resposta em seu devido tempo. Isso prova que o protocolo HTTP é tratado de maneira assíncrona. Esse processo, inclusive, é chamado de pipelining.

Se você já lidou com AJAX por exemplo, já deve ter ouvido falar sobre o termo callback. Nós precisamos apelar para callbacks (ou promisses ou observables) justamente por causa desta característica do protocolo HTTP: nós precisamos de uma resposta do servidor, mas, pelo cliente fazer a requisição de maneira assíncrona, nós não sabemos exatamente quando essa resposta vai chegar… Por isso criamos callbacks (ou promisses ou observables) para serem executados quando o ciclo request-response for finalmente concluído.

  • As conexões no protocolo HTTP são independentes: como as conexões são abertas e fechadas a medida que algum conteúdo precisa ser trafegado, as conexões acabam sendo independentes umas das outras. Junto à característica assíncrona do protocolo HTTP, isso torna tecnicamente inviável que uma conexão possa “se comunicar” com alguma outra que esteja em curso, ou mesmo conhecer quais outros ciclos request-response estão em curso em determinado momento;

  • O protocolo HTTP é “stateless”: por decorrência dos três últimos pontos, nós afirmamos que o protocolo HTTP é stateless, ou seja, ele não guarda estado das requisições. Mais uma vez, isso é inviável, já que as conexões HTTP são independentes, assíncronas e, principalmente, por não serem keep alive. Se a conexão é imediatamente fechada após sua utilização, como podemos guardar alguma informação sobre ela? É exatamente por essa característica do protocolo HTTP que acabamos utilizando técnicas (como os cookies) para tentar guardar alguma informação necessária, como o usuário que está logado em uma aplicação por exemplo.

  • O protocolo HTTP é semântico: os recursos que podem ser disponibilizados por um servidor HTTP (como um página, por exemplo) podem ser acessados através de URIs (Unique Resource Identifier), que podem ser “traduzidas” para URLs (Unique Resource Locator). O grande ponto é que um servidor Web pode disponibilizar não somente páginas, ele também pode, por exemplo, fazer um upload de um arquivo. Para traduzir o que deve ser feito no servidor, o protocolo HTTP disponibiliza algo que nós chamamos de verbo ou método HTTP. A idéia é que esse verbo, associado ao request, indique o que deve ser feito no servidor.

Nós temos vários verbos HTTP, mas os principais, de maneira sucinta, são:

1) GET: indica que um recurso será recuperado do servidor. Por exemplo, quando você solicita uma página pelo seu browser;

2) POST: indica que um recurso será inserido ou criado no servidor. Um upload de um novo arquivo, por exemplo;

3) PUT: indica que um recurso será atualizado no servidor. Seria equivalente a um update em uma base de dados;

4) DELETE: indica que um recurso será removido do servidor. Seria o equivalente a um delete em uma base de dados.

Isso quer dizer que nós podemos invocar uma mesma URL (ou URI) em uma requisição HTTP, porém, dependendo da atribuição do verbo HTTP, a requisição irá desempenhar uma tarefa diferente no servidor. O verbo HTTP acaba determinando a semântica – ou significado/intenção – da requisição HTTP.

E o JSON? Onde ele entra na jogada?

O JSON (JavaScript Object Notation) não é um protocolo de transporte de informações como o HTTP. Ele é somente uma forma bem leve de representação e troca de informações. Ele tem a única função de levar informações de um lado para o outro. Nós podemos utilizar o JSON para transportar informações entre mensagens HTTP.

JSON x XML


Mas calma! A “treta” não precisa começar, rs

O XML também é uma forma de representação de informações. Porém, é uma forma mais “pesada” e verbosa de representação, já que preza pela “legibilidade” das informações a serem representadas.

Veja, por exemplo, um fragmento de um XML:

<clientes>
    <cliente>
        <id>1</id>
        <nome>TreinaWeb Cursos</nome>
        <idade>10</idade>
    </cliente>
</clientes>

A mesma informação acima poderia ser representada facilmente com o JSON abaixo:

"clientes" : [
    {
        "id" : 1,
        "nome" : "TreinaWeb Cursos",
        "idade" : 10
    }
]

Veja que, apesar de não ser tão explícita, a forma de representação com o JSON é muito mais direta e simples do que através do XML. Perceba também a quantidade de caracteres utilizados em cada uma das representações… Isso é um ponto muito importante! Como o JSON utiliza menos caracteres que o XML, ele também vai ocupar menos bytes dentro de um response com relação ao XML e, por consequência, o download de um response que contenha dados no formato JSON será mais rápido do que um response com as mesmas informações no formato XML. Essa é uma das principais justificativas para os desenvolvedores preferirem utilizar JSON do que XML para o intercâmbio de informações.

Então, o REST e o JSON possuem responsabilidades completamente diferentes!?


Me desculpa se isso foi um balde de água fria… 🙁

Sim, exatamente esse é o ponto! REST é um conceito arquitetural muito complexo, mas que no fim visa tirar vantagem de todas as características do protocolo HTTP, que é um protocolo de transporte. O JSON é somente uma forma de representar informações que precisam ser transportadas de um lado para outro. Sendo assim, podemos utilizar o protocolo HTTP para fazer o transporte de dados entre um cliente e um servidor.

Para conseguir utilizar o protocolo HTTP da forma correta, nós podemos adotar uma arquitetura baseada no REST. Agora, para fazer a representação das informações que precisam ser transportadas através do protocolo HTTP em uma arquitetura REST, nós podemos utilizar o JSON.

Mas então, eu posso ter uma API REST que responde XML?


Isso pode ser interessante…

Absolutamente, sim! Você, neste caso, só estará alterando a forma como as informações serão representadas nas requisições HTTP. Lembre-se: as responsabilidades do HTTP, do REST, do JSON e do XML são completamente diferentes. Isso, inclusive, é um trunfo da arquitetura REST: a representação das informações e o modo de transporte destas são completamente desacopladas.

Inclusive, é muito comum que APIs aceitem dados tanto no formato XML quanto no formato JSON, além de também responderem nestes dois formatos. As linguagens modernas hoje praticamente oferecem suporte nativo ao formato JSON, o que faz com que a adoção deste seja mais popular. Mas muitos sistemas, principalmente os sistemas legados, ainda são fundamentados no formato XML. Por isso é interessante que as APIs respondam nos dois formatos. Inclusive, as APIs definem a forma como vão fazer a leitura das informações com base no formato com que estas estão representadas, bem como definem o formato de dados a ser utilizado para a resposta, em uma etapa chamada content negociation.

“Perceba a petulância do protocolo HTTP!”


Do clássico meme “Percebe, Ivair, a petulância do cavalo!”

E ele é petulante com muita razão, haha. Afinal, toda a web hoje é fundamentada nele. Qualquer transporte de informação que for necessário entre aplicações hoje em dia passará pelo HTTP. Perceba como as características dele justificam muitas coisas que nós sem querer fazemos no automático quando estamos desenvolvendo soluções baseadas na Web.

Eu costumo dizer que entender os princípios básicos do protocolo HTTP é importantíssimo para qualquer desenvolvedor Web hoje em dia. Quando o desenvolvedor sabe como que as coisas “funcionam por baixo dos panos”, ele se preocupa mais com a maneira como ele vai desenvolvedor, além de entender bem melhor o porquê de algumas coisas serem do jeito que são.

Agora, deixa eu aproveitar o momento para fazer um “jabá”, hahaha: sabia que temos aqui no TreinaWeb um curso sobre o protocolo HTTP? Se você se interessar:

HTTP - Fundamentos
Curso de HTTP - Fundamentos
CONHEÇA O CURSO

© 2004 - 2019 TreinaWeb Tecnologia LTDA - CNPJ: 06.156.637/0001-58 Av. Paulista, 1765, Conj 71 e 72 - Bela Vista - São Paulo - SP - 01311-200