Nota: O seguinte artigo irá ajudá-lo com: Como habilitar o CORS com o cookie HTTPOnly para proteger o token?
Neste artigo, vemos como habilitar o CORS (Cross-Origin Resource Sharing) com o cookie HTTPOnly para proteger nossos tokens de o.
Atualmente, servidores back-end e clientes front-end são implantados em diferentes domínios. Portanto, o servidor deve habilitar o CORS para permitir que os clientes se comuniquem com o servidor nos navegadores.
Além disso, os servidores estão implementando a autenticação sem estado para melhor escalabilidade. Os tokens são armazenados e mantidos no lado do cliente, mas não no lado do servidor, como na sessão. Por segurança, é melhor armazenar tokens em cookies HTTPOnly.
Por que as solicitações de origem cruzada são bloqueadas?
Vamos supor que nosso aplicativo front-end foi implantado em https://app.geekflare.com. Um script carregado em https://app.geekflare.com só pode solicitar recursos da mesma origem.
Sempre que tentamos enviar uma solicitação de origem cruzada para outro domínio https://api.geekflare.com ou outra porta https://app.geekflare.com:3000 ou outro esquema http://app.geekflare.com, o solicitação de origem cruzada será bloqueada pelo navegador.
Mas por que a mesma solicitação bloqueada pelo navegador ser enviada de qualquer servidor backend usando a solicitação curl ou enviada usando ferramentas como o carteiro sem nenhum problema de CORS. Na verdade, é para a segurança proteger os usuários de ataques como CSRF (Cross-Site Request Forgery).
Vamos dar um exemplo, suponha que algum usuário tenha feito em sua própria conta do PayPal em seu navegador. Se pudermos enviar uma solicitação de origem cruzada para paypal.com a partir de um script carregado em outro domínio malicioso.com sem nenhum erro/bloqueio de CORS, como enviamos a solicitação de mesma origem.
Os invasores podem facilmente enviar sua página maliciosa https://malicious.com/transfer-money-to-attacker--from--paypal- convertendo-a em URL curto para ocultar a URL real. Quando o usuário clica em um link malicioso, o script carregado no domínio malicioso.com enviará uma solicitação de origem cruzada ao PayPal para transferir o valor do usuário para a conta do PayPal do invasor. Todos os usuários que fizeram em sua conta do PayPal e clicaram neste link malicioso perderão seu dinheiro. Qualquer pessoa pode facilmente roubar dinheiro sem o conhecimento de um usuário de conta do PayPal.
Pelo motivo acima, os navegadores bloqueiam todas as solicitações de origem cruzada.
O que é CORS (Cross-Origin Resource Sharing)?
CORS é um mecanismo de segurança baseado em cabeçalho usado pelo servidor para informar ao navegador para enviar uma solicitação de origem cruzada de domínios confiáveis.
O servidor habilitado com cabeçalhos CORS usados para evitar solicitações de origem cruzada bloqueadas pelos navegadores.
Como funciona o CORS?
Como o servidor já definiu seu domínio confiável em sua configuração CORS. Quando enviamos uma solicitação ao servidor, a resposta informará ao navegador que o domínio solicitado é confiável ou não em seu cabeçalho.
Existem dois tipos de solicitações CORS:
- Solicitação simples
- Solicitação de simulação
Pedido Simples:
- O navegador envia a solicitação para um domínio de origem cruzada com origem(https://app.geekflare.com).
- O servidor envia de volta a resposta correspondente com métodos permitidos e origem permitida.
- Após receber a solicitação, o navegador verificará o valor do cabeçalho de origem enviado (https://app.geekflare.com) e o valor de controle de o-permissão-origem recebido (https://app.geekflare.com) são iguais ou curinga
. Caso contrário, ele lançará um erro CORS.
- CORS-Preflight Request Imagem que mostra o fluxo de solicitação de origem cruzada com a solicitação de comprovação OPTIONS antes de enviar a solicitação real para verificar os cabeçalhos.
- Dependendo do parâmetro de solicitação personalizada da solicitação de origem cruzada, como métodos (PUT, DELETE) ou cabeçalhos personalizados ou tipo de conteúdo diferente, etc. O navegador decidirá enviar uma solicitação OPTIONS de comprovação para verificar se a solicitação real é segura para enviar ou não. Depois de receber a resposta (código de status: 204, o que significa sem conteúdo), o navegador verificará o controle de o-permitir
parâmetros para a solicitação real. Se os parâmetros de solicitação são permitidos pelo servidor. A solicitação de origem cruzada real enviada e recebida
Se access-control-allow-origin: *, a resposta é permitida para todas as origens. Mas não é seguro a menos que você precise.
Como habilitar o CORS?
Para habilitar o CORS para qualquer domínio, habilite os cabeçalhos CORS para permitir origem, métodos, cabeçalhos personalizados, credenciais, etc.
- O navegador lê o cabeçalho CORS do servidor e permite solicitações reais do cliente somente após verificar os parâmetros da solicitação. o-Controle-Permitir-Origem:
- Para especificar domínios exatos (https://app.geekflate.com, https://lab.geekflare.com) ou curinga
- Métodos de controle de o-permissão: Para permitir os métodos HTTP (GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS) que só precisamos.
- Cabeçalhos de permissão de controle de o: Para permitir apenas cabeçalhos específicos (autorização, csrf-token)
- o-Controle-Permitir-Credenciais: Valor booleano usado para permitir credenciais de origem cruzada (cookies, cabeçalho de autorização).
- o-Controle-Max-Idade: Diz ao navegador para armazenar em cache a resposta de comprovação por algum tempo.
Cabeçalhos de o-controle-exposição:
Especifique os cabeçalhos que podem ser ados pelo script do lado do cliente.
Para habilitar o CORS no apache e no servidor web Nginx, siga este tutorial.
const express = require('express'); const app = express() app.get('/s', function (req, res, next) { res.json({msg: ' get'}) }); app.post('/s', function (req, res, next) { res.json({msg: ' create'}) }); app.put('/s', function (req, res, next) { res.json({msg: ' update'}) }); app.listen(80, function () { console.log('CORS-enabled web server listening on port 80') })
Habilitando CORS no ExpressJS
Vamos dar um exemplo de aplicativo ExpressJS sem CORS: No exemplo acima, habilitamos o endpoint da API dos usuários para os métodos POST, PUT, GET, mas não para o método DELETE.
npm install cors
Para facilitar a ativação do CORS no aplicativo ExpressJS, você pode instalar o
núcleos
app.use(cors({ origin: '*' }));
o-Controle-Permitir-Origem
app.use(cors({ origin: 'https://app.geekflare.com' }));
Habilitando CORS para todos os domínios Habilitando CORS para um único domínio Se você deseja permitir CORS para origem https://app.geekflare.com
app.use(cors({ origin: [ 'https://app.geekflare.com', 'https://lab.geekflare.com' ] }));
e
https://lab.geekflare.com
app.use(cors({ origin: [ 'https://app.geekflare.com', 'https://lab.geekflare.com' ], methods: ['GET', 'PUT', 'POST'] }));
Métodos de controle de o-permissão
Para habilitar CORS para todos os métodos, omita esta opção no módulo CORS no ExpressJS. Mas para habilitar métodos específicos (GET, POST, PUT).
app.use(cors({ origin: [ 'https://app.geekflare.com', 'https://lab.geekflare.com' ], methods: ['GET', 'PUT', 'POST'], allowedHeaders: ['Content-Type', 'Authorization', 'x-csrf-token'] }));
Cabeçalhos-Controle-o-Permitir-
Usado para permitir que cabeçalhos diferentes dos padrões sejam enviados com solicitações reais. o-Controle-Permitir-Credenciais Omita isso se você não quiser dizer ao navegador para permitir credenciais mediante solicitação, mesmo emcom credenciais
app.use(cors({ origin: [ 'https://app.geekflare.com', 'https://lab.geekflare.com' ], methods: ['GET', 'PUT', 'POST'], allowedHeaders: ['Content-Type', 'Authorization', 'x-csrf-token'], credentials: true }));
está definido como verdadeiro
.
app.use(cors({ origin: [ 'https://app.geekflare.com', 'https://lab.geekflare.com' ], methods: ['GET', 'PUT', 'POST'], allowedHeaders: ['Content-Type', 'Authorization', 'x-csrf-token'], credentials: true, maxAge: 600 }));
o-Controle-Max-Idade
Para intimar o navegador a armazenar em cache as informações de resposta de comprovação no cache por um segundo especificado. Omita isso se você não quiser armazenar em cache a resposta.
app.use(cors({ origin: [ 'https://app.geekflare.com', 'https://lab.geekflare.com' ], methods: ['GET', 'PUT', 'POST'], allowedHeaders: ['Content-Type', 'Authorization', 'x-csrf-token'], credentials: true, maxAge: 600, exposedHeaders: ['Content-Range', 'X-Content-Range'] }));
A resposta de comprovação em cache ficará disponível por 10 minutos no navegador. Cabeçalhos de o-controle-exposição Se colocarmos o curinga
app.use(cors({ origin: [ 'https://app.geekflare.com', 'https://lab.geekflare.com' ], methods: ['GET', 'PUT', 'POST'], allowedHeaders: ['Content-Type', 'Authorization', 'x-csrf-token'], credentials: true, maxAge: 600, exposedHeaders: ['*', 'Authorization', ] }));
dentro
cabeçalhos expostos,
ele não irá expor o cabeçalho Authorization. Então, temos que expor explicitamente como abaixo
O acima irá expor todos os cabeçalhos e cabeçalho de autorização também.
- O que é um cookie HTTP? Um cookie é um pequeno pedaço de dados que o servidor enviará ao navegador do cliente. Em solicitações posteriores, o navegador enviará todos os cookies relacionados ao mesmo domínio em todas as solicitações.
- Cookie tem seu atributo, que pode ser definido para fazer um cookie funcionar de forma diferente conforme a necessidade. Nome
- Nome do biscoito. valor:
- dados do cookie relativos ao nome do cookie Domínio:
- cookies serão enviados apenas para o domínio definido Caminho:
- cookies enviados somente após o caminho de prefixo de URL definido. Suponha que definimos nosso caminho de cookie como path=’/’. Cookies não enviados para o URL https://geekflare.com/expire/ mas enviados com o prefixo de URL https://geekflare.com// Max-Age/Expires(número em segundo):
- Quando o cookie deve expirar. Uma vida útil do cookie torna o cookie inválido após o tempo especificado. HTTPOnly(Booleano):
- O servidor de back-end pode ar esse cookie HTTPOnly, mas não o script do lado do cliente quando verdadeiro. [Strict, Lax, None]Seguro(Booleano): Cookies enviados apenas por um domínio SSL/TLS quando verdadeiros.
mesmoSite(string
): Usado para ativar/restringir cookies enviados em solicitações entre sites. Para saber mais detalhes sobre cookies SameSite consulte MDN. Aceita três opções Strict, Lax, None. Valor seguro do cookie definido como true para a configuração do cookie sameSite=None.Por que cookie HTTPOnly para tokens? Armazenar o token de o enviado do servidor no armazenamento do lado do cliente, como armazenamento local , banco de dados indexado,
e
bolacha
(HTTPOnly não definido como verdadeiro) são mais vulneráveis ao ataque XSS. Suponha que qualquer uma de suas páginas seja fraca para um ataque XSS. Os invasores podem fazer uso indevido de tokens de usuário armazenados no navegador.
Os cookies HTTPOnly são definidos/obtidos apenas pelo servidor/backend, mas não no lado do cliente.
- Script do lado do cliente para ar esse cookie HTTPonly. Portanto, os cookies HTTPOnly não são vulneráveis a ataques XSS e são mais seguros. Porque só é ível pelo servidor.
- Habilitar cookie HTTPOnly no back-end habilitado para CORS
- Habilitar Cookie no CORS precisa da configuração abaixo na aplicação/servidor.
- Defina o cabeçalho Access-Control-Allow-Credentials como true.
Access-Control-Allow-Origin e Access-Control-Allow-Headers não devem ser um curinga
const express = require('express'); const app = express(); const cors = require('cors'); app.use(cors({ origin: [ 'https://app.geekflare.com', 'https://lab.geekflare.com' ], methods: ['GET', 'PUT', 'POST'], allowedHeaders: ['Content-Type', 'Authorization', 'x-csrf-token'], credentials: true, maxAge: 600, exposedHeaders: ['*', 'Authorization' ] })); app.post('/', function (req, res, next) { res.cookie('access_token', access_token, { expires: new Date(Date.now() + (3600 * 1000 * 24 * 180 * 1)), //second min hour days year secure: true, // set to true if your using https or samesite is none httpOnly: true, // backend only sameSite: 'none' // set to none for cross-request }); res.json({ msg: ' Successfully', access_token }); }); app.listen(80, function () { console.log('CORS-enabled web server listening on port 80') });
.
O atributo SameSite do cookie deve ser Nenhum.
Para habilitar o valor sameSite como none, defina o valor seguro como true: Habilite o back-end com certificado SSL/TLS para funcionar no nome de domínio.
Vamos ver um código de exemplo que define um token de o no cookie HTTPOnly após verificar as credenciais de .
Você pode configurar cookies CORS e HTTPOnly implementando as quatro etapas acima em seu idioma de back-end e servidor web.
var xhr = new XMLHttpRequest(); xhr.open('GET', 'http://api.geekflare.com/', true); xhr.withCredentials = true; xhr.send(null);
Você pode seguir este tutorial para apache e Nginx para habilitar o CORS seguindo as etapas acima.
fetch('http://api.geekflare.com/', { credentials: 'include' });
withCredentials for Cross-Origin request
$.ajax({ url: 'http://api.geekflare.com/', xhrFields: { withCredentials: true } });
Credenciais (Cookie, Autorização) enviadas com a solicitação de mesma origem por padrão. Para origem cruzada, temos que especificar o withCredentials como true.
axios.defaults.withCredentials = true
API XMLHttpRequest
Buscar API
JQuery AjaxAxiosConclusão Espero que o artigo acima ajude você a entender como o CORS funciona e habilitar o CORS para solicitações de origem cruzada no servidor. Por que armazenar cookies em HTTPOnly é seguro e como withCredentials usado em clientes para solicitações de origem cruzada.