20 set 2017

Resolvendo o problema do CORS com Angular e @angular/cli

CORS é um “problema” comum que todos esbarram ao iniciar seus estudos com um framework moderno, sendo novo na área ou simplesmente migrando de uma tecnologia de renderização server-side.

Nesse post vou mostrar como lidar com CORS quando em uma aplicação Angular usando o @angular/cli, mas antes vamos conversar um pouco sobre CORS.

O que é CORS?

Cross-origin resource sharing ou compartilhamento de recursos de origem cruzada é uma especificação de segurança de navegadores que tem como intenção fazer a segurança de recursos de diferentes origens.

É difícil entender esse erro logo de início já que você esta desenvolvendo local, tanto front-end quanto back-end, e em nenhum momento foi colocado restrições de acesso no back-end (E pra ajudar, quando você testa no Postman a requisição funciona).

Como ele funciona?

Como dito anteriormente, o CORS é uma especificação de segurança de navegadores, assim é o seu navegador em que você esta desenvolvendo sua aplicação que esta barrando suas requisições.

Isso ocorre pois os navegadores usam a técnica de preflight, uma requisição de verificação que seu browser faz ao recurso que você deseja consumir e verifica se sua requisição para consumi-lo está de acordo com as políticas de CORS definidas no back-end.

As políticas do CORS são baseadas na origem (domínio) da requisição, headers aceitos pelo back-end e os verbos HTTP disponíveis.

Resumindo de maneira grosseira, CORS é uma whitelist configurada no seu back-end e caso você não esteja incluso nela o navegador não realiza sua requisição.

Como lidar com ele?

Para resolver esse problema você pode configurar o back-end para que qualquer domínio possa acessa-lo com aquele famoso Access-Control-Allow-Origin: * que encontramos espalhado em várias perguntas e respostas do StackOverflow.

Mas se sua aplicação não precisa dessa configuração para por outros motivos além de não impedir o desenvolvimento do front-end, essa não é a melhor abordagem.

Você como um bom front-end deve estar desenvolvendo sua aplicação com seu próprio servidor servindo suas páginas, e muito provavelmente esse servidor tem como configurar Proxy nele. E essa é a solução, porque com ele você fará suas requisições para seu próprio servidor que prove suas páginas e ele fará a requisição ao back-end por baixo dos panos. E como o CORS é algo validado pelo browser, você estará livre das verificações de CORS.

Como configurar proxy usando o @angular/cli?

Cenário:

  • Front-end servido em http://localhost:4200
  • Back-end servido em http://localhost:8080

Crie um arquivo proxy.config.js no mesmo diretório em que se encontra o seu package.json:

1
2
3
4
5
6
7
8
const proxy = [
  {
    context: '/api',
    target: 'http://localhost:8080',
    pathRewrite: { '^/api': '' }
  }
];
module.exports = proxy;

Explicando o arquivo:

context: ‘O contexto que deve ser requisitado para tratar o proxy/redirecionamento da requisição’

target: ‘endpoint ao qual você quer que seja feito o proxy/redirecionamento’

pathRewrite: ‘Objeto opcional em que você escreve uma expressão regular como atributo e o que deve substituir o resultado da expressão para reescrever a url resultado do proxy/redirecionamento’

Exemplos:
Sem pathRewrite
http://localhost:4200/api/user => http://localhost:8080/api/user

Com pathRewrite: { ‘^/api’: ” }
http://localhost:4200/api/user => http://localhost:8080/user

Com pathRewrite: { ‘^/api’: ‘/bacon’ }
http://localhost:4200/api/user => http://localhost:8080/bacon/user

Agora edite o script de start de sua aplicação no package.json:

1
2
3
4
...
"scripts": {
  "start": "ng serve --proxy-config proxy.conf.js",
...

Pronto, agora seu servidor de desenvolvimento já esta com o Proxy configurado e pronto para te ajudar a contornar o CORS durante o desenvolvimento do projeto.

Só lhe resta ajustar as urls que seu app requisita para apontar ao seu server de proxy, de http://localhost:8080/path/do/recurso para http://localhost:4200/api/path/do/recurso.

Obrigado pela leitura, esse post foi baseado no meu post do medium, de uma olhada lá também: Resolvendo o problema do CORS com Angular e o @angular/cli

Comments

  • Henrique Lobo Weissmann
    setembro 22, 2017 Responder

    Muito bacana este blog, não conhecia!
    Mantenho um projeto chamado /dev/All, que é um agregador de blogs de desenvolvedores.
    Cadastrem este blog lá pro pessoal acompanhar, tem muito conteúdo bom aqui!

    Segue o link do /dev/All – http://www.devall.com.br

Leave a Comment