CORS: o modo de credenciais é 'incluir'

103

Sim, eu sei o que você está pensando - mais uma pergunta CORS, mas desta vez estou perplexo.

Portanto, para começar, a mensagem de erro real:

XMLHttpRequest não pode carregar http: //localhost/Foo.API/token . O valor do cabeçalho 'Access-Control-Allow-Origin' na resposta não deve ser o caractere curinga '*' quando o modo de credenciais da solicitação é 'incluir' . Portanto, o acesso de origem ' http: // localhost: 5000 ' não é permitido. O modo de credenciais de solicitações iniciadas pelo XMLHttpRequest é controlado pelo atributo withCredentials.

Não tenho certeza se o significado de modo de credenciais é 'incluir' ?

Então, quando eu executar o pedido no carteiro, eu experimentar nenhum tal erro:

insira a descrição da imagem aqui

Mas quando eu acesso a mesma solicitação por meio do meu aplicativo da web angularjs, fico perplexo com esse erro. Aqui está o meu pedido / resposta angualrjs. Como você verá, a resposta é OK 200, mas ainda recebo o erro CORS:

Solicitação e resposta do Fiddler:

A imagem a seguir demonstra a solicitação e a resposta do front-end da web para API

Violinista

Portanto, com base em todas as outras postagens que li online, parece que estou fazendo a coisa certa, por isso não consigo entender o erro. Por último, aqui está o código que uso no angualrjs (fábrica de login):

insira a descrição da imagem aqui

Implementação do CORS na API - fins de referência:

Método 1 usado:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        EnableCrossSiteRequests(config);
    }

    private static void EnableCrossSiteRequests(HttpConfiguration config)
    {
        var cors = new EnableCorsAttribute("*", "*", "*")
        {
            SupportsCredentials = true
        };
        config.EnableCors(cors);
    }
}

Método 2 usado:

public void Configuration(IAppBuilder app)
{
    HttpConfiguration config = new HttpConfiguration();

    ConfigureOAuth(app);

    WebApiConfig.Register(config);
    app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
    app.UseWebApi(config);

}

Muito obrigado antecipadamente!

Richard Bailey
fonte
belas fotos, do que são? Para responder à sua pergunta, se você incluir autenticação, a resposta access-control-allow-origin deve ser o host de origem (página do navegador), não pode ser *- então, o lado do servidor está executando CORS errado - oh, e o carteiro funciona porque não é uma solicitação de origem cruzada
Jaromanda X
@JaromandaX, obrigado pela resposta. As imagens demonstram solicitação / resposta, bem como demonstram os cabeçalhos sendo passados. Você está fazendo a pergunta, obviamente afirma que não cumpriu seu objetivo ...
Richard Bailey
Meu comentário deve ser tudo que você precisa saber - não precisava ver as fotos
Jaromanda X
Recentemente, decidi deixar de usar cookies em minha API da web e preferir usar tokens. Quando usei cookies, meu CORS funcionou sem problemas. Estou me esforçando para entender como o CORS não é implementado corretamente no lado do servidor
Richard Bailey
1
se você incluir autenticação, a access-control-allow-originresposta deve ser o host de origem (página do navegador), não pode ser*
Jaromanda X

Respostas:

104

O problema decorre do seu código Angular:

Quando withCredentialsdefinido como verdadeiro, ele está tentando enviar credenciais ou cookies junto com a solicitação. Como isso significa que outra origem está potencialmente tentando fazer solicitações autenticadas, o curinga ("*") não é permitido como o cabeçalho "Access-Control-Allow-Origin".

Você teria que responder explicitamente com a origem que fez a solicitação no cabeçalho "Access-Control-Allow-Origin" para fazer este trabalho.

Eu recomendaria colocar explicitamente na lista de permissões as origens que você deseja permitir para fazer solicitações autenticadas, porque simplesmente responder com a origem da solicitação significa que qualquer site pode fazer chamadas autenticadas para seu back-end se o usuário tiver uma sessão válida.

Eu explico essas coisas neste artigo que escrevi há um tempo.

Portanto, você pode definir withCredentialscomo falso ou implementar uma lista de permissões de origem e responder às solicitações CORS com uma origem válida sempre que as credenciais estiverem envolvidas

geekonauta
fonte
4
Estou trabalhando no aplicativo Angular 5 com TypeScript. Preciso fornecer withCredentials como true, caso contrário, receberei a exceção Authorization Failed. Como resolver isso com credenciais: true
Ziggler
@Ziggler Eu tive a mesma situação. Você encontra soluções?
Pavel
@Ziggler Eu multou solução veja minha resposta.
Pavel
1
Ainda estou recebendo este erro ao usar WithCredentials = TRUE e Access-Control-Allow-Origin = [' localhost: 4200'] , e NÃO estou usando estrela *, então a mensagem de erro não faz mais sentido. MENSAGEM DE ERRO: "Resposta à solicitação de comprovação não passa na verificação de controle de acesso: O valor do cabeçalho 'Access-Control-Allow-Origin' na resposta não deve ser o caractere curinga * quando o modo de credenciais da solicitação é 'incluir'. Origem ' localhost: 4200 ', portanto, não tem acesso permitido. O modo de credenciais das solicitações iniciadas pelo XMLHttpRequest é controlado pelo atributo withCredentials. "
mruanova
@mruanova tem certeza de que o cabeçalho Access-Control-Allow-Origin está definido corretamente na solicitação? Parece que algo foi enviado com um caractere curinga em algum lugar
geekonaut de
15

Se você estiver usando middleware CORS e quiser enviar withCredentialsbooleano verdadeiro, poderá configurar o CORS assim:

var cors = require('cors');    
app.use(cors({credentials: true, origin: 'http://localhost:5000'}));

`

Ankur Kedia
fonte
11

Customizando CORS para Angular 5 e Spring Security (solução de base de cookies)

No lado angular, é necessário adicionar sinalizador de opção withCredentials: truepara transporte de cookies:

constructor(public http: HttpClient) {
}

public get(url: string = ''): Observable<any> {
    return this.http.get(url, { withCredentials: true });
}

No lado do servidor Java, é necessário adicionar CorsConfigurationSourcepara a política CORS de configuração:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        // This Origin header you can see that in Network tab
        configuration.setAllowedOrigins(Arrays.asList("http:/url_1", "http:/url_2")); 
        configuration.setAllowedMethods(Arrays.asList("GET","POST"));
        configuration.setAllowedHeaders(Arrays.asList("content-type"));
        configuration.setAllowCredentials(true);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and()...
    }
}

Método configure(HttpSecurity http)padrão será usado corsConfigurationSourceparahttp.cors()

Pavel
fonte
1

Se ajudar, eu estava usando centrifuge com meu aplicativo reactjs e, depois de verificar alguns comentários abaixo, olhei o arquivo de biblioteca centrifuge.js, que em minha versão tinha o seguinte snippet de código:

if ('withCredentials' in xhr) {
 xhr.withCredentials = true;
}

Depois de remover essas três linhas, o aplicativo funcionou bem, conforme o esperado.

Espero que ajude!

Gustavo garcia
fonte
1

Se estiver usando o .NET Core, você terá que .AllowCredentials () ao configurar o CORS no Startup.CS.

Dentro de ConfigureServices

services.AddCors(o => {
    o.AddPolicy("AllowSetOrigins", options =>
    {
        options.WithOrigins("https://localhost:xxxx");
        options.AllowAnyHeader();
        options.AllowAnyMethod();
        options.AllowCredentials();
    });
});

services.AddMvc();

Então, dentro do Configure:

app.UseCors("AllowSetOrigins");
app.UseMvc(routes =>
    {
        // Routing code here
    });

Para mim, foi especificamente a falta de options.AllowCredentials () que causou o erro que você mencionou. Como uma observação lateral em geral para outros que tenham problemas com CORS também, o pedido é importante e AddCors () deve ser registrado antes de AddMVC () dentro de sua classe de inicialização.

Steven Pfeifer
fonte
0

Basta adicionar em Axios.defaults.withCredentials=truevez de ( {credentials: true}) no lado do cliente e mudar app.use(cors())para

app.use(cors(
  {origin: ['your client side server'],
  methods: ['GET', 'POST'],
  credentials:true,
}
))
Dev Essence
fonte