https://github.com/zerg000000/simple-cors
Simply usable CORS middleware / interceptor for Clojure
https://github.com/zerg000000/simple-cors
clojure-ring cors reitit
Last synced: 6 months ago
JSON representation
Simply usable CORS middleware / interceptor for Clojure
- Host: GitHub
- URL: https://github.com/zerg000000/simple-cors
- Owner: zerg000000
- License: mit
- Created: 2020-11-11T10:42:39.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2023-06-27T02:52:14.000Z (almost 3 years ago)
- Last Synced: 2025-09-27T22:30:49.118Z (7 months ago)
- Topics: clojure-ring, cors, reitit
- Language: Clojure
- Homepage:
- Size: 73.2 KB
- Stars: 28
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
# Simple CORS
[](https://clojars.org/zerg000000/simple-cors)
Bare minimum CORS middleware/interceptor for Clojure.
## Features
* Provide just enough CORS required by [Browser](https://fetch.spec.whatwg.org/#cors-protocol).
* Reasonable performance
* Support Ring middleware / Reitit interceptor / Aleph middleware
* Support all CORS features, especially `Access-Control-Max-Age`
## Get Started
Add to your deps.edn
```clojure
{zerg000000/simple-cors {:mvn/version "0.0.8"}}
```
When use in [Ring](https://github.com/ring-clojure/ring) handler
```clojure
(require '[simple-cors.ring.middleware :as cors])
(def app (cors/wrap handler {:cors-config {:allowed-request-methods [:post :get]
:allowed-request-headers ["Authorization" "Content-Type"]
:origins ["https://yahoo.com"
"https://google.com"]
:max-age 300}}))
```
When use in [Reitit](https://github.com/metosin/reitit)
```clojure
(require '[simple-cors.reitit.interceptor :as cors]
'[reitit.interceptor.sieppari]
'[reitit.http :as http])
(def app
(let [config {:cors-config {:allowed-request-methods [:post :get]
:allowed-request-headers ["Authorization" "Content-Type"]
:origins ["https://yahoo.com"
"https://google.com"]
:max-age 300}}]
(http/ring-handler
(http/router routes
{:reitit.http/default-options-endpoint
(cors/make-default-options-endpoint config)})
{:executor reitit.interceptor.sieppari/executor
:interceptors [(cors/cors-interceptor config)]})))
```
When use in [Aleph](https://github.com/aleph-io/aleph)
```clojure
(require '[simple-cors.aleph.middleware :as cors])
(def app (cors/wrap handler {:cors-config {:allowed-request-methods [:post :get]
:allowed-request-headers ["Authorization" "Content-Type"]
:origins ["https://yahoo.com"
"https://google.com"]
:max-age 300}}))
```
Full config map, you can also see the spec in `simple-cors.specs`
```clojure
{:cors-config {:allowed-request-methods [:post :get]
:allowed-request-headers ["Authorization" "Content-Type"]
:allow-credentials? true
:origins ["https://yahoo.com"
"https://google.com"]
:max-age 300
:exposed-headers ["x-amz-date"]}
:preflight-forbidden-response {:status 403}
:preflight-ok-response {:status 200}}
```
### Static / Any Origin / Fn CORS
Normally, Static is good and enough
```clojure
{:cors-config {...
:origins ["https://whatever.co"]
...}}
```
Some casual user might want CORS matched with any origin
```clojure
{:cors-config {...
:origins "*"
...}}
```
The ultimate solution is to provide your own matching function
```clojure
{:cors-config {...
:origins #{"https://whatever.co"}
...}}
; or
{:cors-config {...
:origins (fn [origin] (and (str/starts-with? origin "https://")
(str/ends-with? origin ".google.com")))
...}}
```
### Combine Multiple Config
Support combining multiple CORS config with performance penalty.
At most one AnyOrigin in configs, and will act as the last fallback.
```clojure
{:cors-config [{...
:origin "*"
...}
{...
:origin ["http://abc"]
...}]}
```
## Why
### Not checking or blocking invalid request
Since the main idea of CORS is to provide information for a browser to take action.
In most of the cases, we can do little on pure server side
## TODO
- [ ] more tests
- [ ] more docstring
## Reference
### Reference Doc
* [whatwg](https://fetch.spec.whatwg.org/#cors-protocol)
* [MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)
### Reference Implementation
* [pedestal](https://github.com/pedestal/pedestal/blob/aa71a3a630dd21861c0682eeeebec762cbf3f85c/service/src/io/pedestal/http/cors.clj)
* [nasus](https://github.com/kachayev/nasus/blob/371d60e08948c52c56ae1f0ac3f39f4105383aaf/src/http/server.clj#L317)
* [netty](https://github.com/barchart/barchart-project-netty/blob/master/codec-http/src/main/java/io/netty/handler/codec/http/cors/CorsHandler.java)
## License
Copyright © 2020 Simple CORS
Simple CORS is licensed under the MIT license, available at MIT and also in the LICENSE file.