Aircoookie / WLED

Control WS2812B and many more types of digital RGB LEDs with an ESP8266 or ESP32 over WiFi!
https://kno.wled.ge
MIT License
14.92k stars 3.22k forks source link

CORS Support #99

Closed Shaegi closed 5 years ago

Shaegi commented 5 years ago

Im trying to write a full feature wled home assitant lovelace card.

To do so I need to request the current status of the wled onload of the page. Since WLED doesn't send the right CORS headers or has no option to do so I needed to install a chrome plugin to disable CORS protection. Since this doesnt seem like a good workaround it would be great if you could add CORS Headers (with an option) to the api responses.

Thanks!

Aircoookie commented 5 years ago

Hi! I did some quick research and it seems like there are multiple CORS headers. Could you provide me with an example of the response headers and their contents you'd need for your application to work? Thanks!

Shaegi commented 5 years ago

Thanks for the quick response. Unfortunatly im not a CORS-expert. At the moment im getting this error message Access to fetch at 'http://[wled-ip]/win' from origin 'http://hassio.local:8123' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

According to https://stackoverflow.com/questions/10636611/how-does-access-control-allow-origin-header-work a "Access-Control-Allow-Origin: "-header would help. (maybe instead of there could be a origin URL as option in wled settings?)

rjhllr commented 5 years ago

what worked for me in similar contexts were two things:

Fortunately it's quite easy to debug, just open a codepen or a local domain and try to send an XHR request to the source, it will be blocked by CORS and you can then see why in the dev tools.

aidbish commented 5 years ago

@Shaegi Would you mind sharing your config for adding to Home Assistant. Also the Lovelace card would be a fantastic addition when complete

Shaegi commented 5 years ago

Sure thing. You can find the card on my github page. I will add some further information to install it.

To add it as an odlschool entity light the configuration would be something like As a lightcard this will give you control for brightness, effect and primary color

light:
  - platform: mqtt
    name: 'WLED LED Strip'
    command_topic: "wled/1"
    brightness_command_topic: "wled/1"
    effect_command_topic: "wled/1/api"
    brightness_state_topic: "wled/1/g"
    rgb_state_topic: "wled/1/c"
    rgb_command_topic: "wled/1/col"
    rgb_command_template: "#{{ '%02x%02x%02x' | format(red, green, blue)}}"
    retain: true
    rgb: true
    effect_list: 
    - FX=0
    - FX=1
    - FX=2
    - FX=3
    - FX=4
    - FX=5
    - FX=6
    - FX=11
    - FX=68
    - FX=25
    - FX=60
    - FX=75

(you would need to add all effects)

aidbish commented 5 years ago

Hi @Shaegi Thanks for that does this give you the status of whether light is on or off?

Shaegi commented 5 years ago

The Card would need cors Support for this. As entity Homeassistent will track the State, so as long as you dont Change it from somewhete else it will be in sync.

debsahu commented 5 years ago

@Aircoookie add something like this DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*"); before server.begin()

Aircoookie commented 5 years ago

@debsahu thank you, I will add this as soon as I migrate to asyncwebserver. At the moment, I'm still using esp8266webserver, so it is not possible. Is my current cors implementation not working properly? If I curl -X OPTIONS http://deviceip, I get:

HTTP/1.1 200 OK
< Content-Type: text/html
< Access-Control-Allow-Origin: *
< Access-Control-Max-Age: 10000
< Access-Control-Allow-Methods: PUT,POST,GET,OPTIONS
< Access-Control-Allow-Headers: *
< Content-Length: 0
< Connection: close
Shaegi commented 5 years ago

Mhh..did I miss something? I installed the version with secondary color. Postman-Headers: image

Postman response: image

Chrome Headers:

image

Console: "Access to fetch at 'http://192.168.137.126/win' from origin 'http://hassio.local:8123' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled."

Aircoookie commented 5 years ago

You don't have the latest 0.8.3 version yet (it would include the <cy> tag in the API response). Please try with that again :) It seems like the request was blocked by cors, but in that case the client should have sent an OPTIONS request. For me, every page includes the Access-Control-Allow-Origin: * header.

Shaegi commented 5 years ago

You are right. With the newer version, Ill get the response headers with method options. But I won't get any XML data. Neither in chrome or postman. GET Request will give me data in postman but it won't include the right headers.

Shaegi commented 5 years ago

I tried to fix get it working...Ive adjusted these lines in wled02.xml if (isHTTP){ server.sendHeader("Access-Control-Allow-Origin", "*"); server.sendHeader("Access-Control-Max-Age", "10000"); server.sendHeader("Access-Control-Allow-Methods", "PUT,POST,GET,OPTIONS"); server.sendHeader("Access-Control-Allow-Headers", "*"); server.send(200, "text/xml", obuf); }

which seems to give me the data with cors enabled on the GET Request for the /win endpoint....

Aircoookie commented 5 years ago

Hi again! With 0.8.4 I use the async webserver and it should include all the relevant cors headers! If you'd like, feel free to give it a try!

BartoilPerso commented 5 years ago

I've commented elsewhere about this, but just trying to sort a few things out. If I've let MQTT discovery do it's thing, will this card still work? Or do I need to manually set up the entity in my config.yaml?

Also, is there support for pallets, secondary colours, etc? I'd love to see a HA integration that is as powerful as the web ui for the hardware itself, especially if a user were to add custom patterns or pallets. If this should be marked as a new issue/suggestion elsewhere, please let me know! Thanks in advance!

Shaegi commented 5 years ago

You need to manually add it in config.yaml. I didnt want to dig too deep into hassio configs. If you have some trouble with setting it up just open a ticket in the Card repo. :)