Allow multiple headers with CORS in Suave

I am trying to get my Suave API to accept CORS requests. I followed this snippet here:

http://www.fssnip.net/mL/title/CORS-response-with-Suave

What I will create here:

let setCORSHeaders = setHeader "Access-Control-Allow-Origin" "*" >=> setHeader "Access-Control-Allow-Headers" "content-type" let allow_cors : WebPart = choose [ OPTIONS >=> fun context -> context |> ( setCORSHeaders >=> OK "CORS approved" ) ] let webSite = choose [ allow_cors GET >=> OK "URLs are for wimps. GETting something? This is what you get." ] 

But now I have endpoints that need to pass a token, and these endpoints give errors due to the lack of permitted headers in CORS. My token header is just a "token", so I tried two things, and both of them did not solve the problem.

Attempt # 1

  setHeader "Access-Control-Allow-Origin" "*" >=> setHeader "Access-Control-Allow-Headers" "content-type" >=> setHeader "Access-Control-Allow-Headers" "token" 

This returned an error in which the content-type expression was no longer accepted - this apparently means that the last setHeader overwrites the first, which when viewing the source code here: https://github.com/SuaveIO/suave/blob/master /src/Suave.Tests/HttpWriters.fs , line 113 has a test that for me implies that this is the desired behavior.

Attempt # 2

Based on the answer to this question: How to set the Json answer in a sub web part , I tried to set both headers through a comma separated list:

  setHeader "Access-Control-Allow-Origin" "*" >=> setHeader "Access-Control-Allow-Headers" "Content-Type,token" 

But this gave an error indicating that CORS completely fails:

 No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. The response had HTTP status code 401. 

Also, based on the same question, I tried the following:

  setHeader "Access-Control-Allow-Origin" "*" >=> setHeader "Access-Control-Allow-Headers:content-type" "Accept" >=> setHeader "Access-Control-Allow-Headers:token" "Accept" 

Which gave this answer: Request header field token is not allowed by Access-Control-Allow-Headers in preflight response.

So, how do I resolve any number of headers in a CORS request in Suave?

Edit

Attempt number 3

I used addHeader instead of setHeader :

 let setCORSHeaders = setHeader "Access-Control-Allow-Origin" "*" >=> addHeader "Access-Control-Allow-Headers" "content-type" >=> addHeader "Access-Control-Allow-Headers" "token" 

What now says ... No 'Access-Control-Allow-Origin' header is present on the requested resource.

If I change this first setHeader to addHeader , I still get the same answer.

Fix

  addHeader "Access-Control-Allow-Origin" "*" >=> setHeader "Access-Control-Allow-Headers" "token" >=> addHeader "Access-Control-Allow-Headers" "content-type" >=> addHeader "Access-Control-Allow-Methods" "GET,POST,PUT" 

Was there work? After that there were problems with what was sent, but no more with CORS.

+5
source share
2 answers

Try using addHeader instead of setHeader . Just a few lines below in unit tests being tested, there is a test for addHeader that shows that it has the semantics you are looking for and its documentation says:

Adds the header key with the given value to the list of returned headers, even if that header already exists. This means that Suave will respond to the response with the header indicated by key , with different meanings.

This is similar to the behavior you want.

+4
source

I had a similar problem. Due to past reasons, I am stuck at the moment with verion 1.1.3, although Suave 2.2.1 is available. I am not very familiar with F #, but in the end I managed to get this to work with something like:

 let setCORSHeaders = addHeader "Access-Control-Allow-Origin" "*" >=> setHeader "Access-Control-Allow-Headers" "token" >=> addHeader "Access-Control-Allow-Headers" "content-type" >=> addHeader "Access-Control-Allow-Methods" "GET,POST,PUT" let app = choose [ GET >=> fun context -> context |> ( setCORSHeaders >=> choose [ pathRegex "(.*?)\.(dll|mdb|log)$" >=> dllFilesRequest pathRegex "(.*?)\.(html|css|js|png|jpg|ico|bmp)$" >=> staticFilesRequest path "/" >=> indexRequest path "/index" >=> indexRequest path "/static" >=> staticFilesRequest // ... ] ) POST >=> fun context -> context |> ( setCORSHeaders >=> choose [ path "/something" >=> runSomething // ... ] ) ] 

I am sure there is a pursuer way.

+1
source

Source: https://habr.com/ru/post/1268535/


All Articles