隞乩gist.github.com舀reverse proxied APIs蝭靘:! `6 E0 g" b, Y# D1 x6 }, A
& F9 A* V- P6 X6 f; J$ u
2 t3 p" M) p# V3 t3 x8 h7 G4 R
# CORS header support
( l& I0 P, K! E9 a7 ~+ q( g# o. l0 {; z& J5 e5 `# ]7 k
# One way to use this is by placing it into a file called "cors_support"" _" _4 H! F4 S' W4 q- B
# under your Nginx configuration directory and placing the following3 Q) b6 g" j! ]; f- ]
# statement inside your **location** block(s):" {5 }7 y; t0 N
#
" P0 W) X8 I- f$ J5 g @# include cors_support;4 A% F& Z) q4 A" R' o8 E) ?% g" b
#' ?$ Z/ T& U" ^6 x
# As of Nginx 1.7.5, add_header supports an "always" parameter which
: V1 S$ j& H. |+ d3 I# allows CORS to work if the backend returns 4xx or 5xx status code.6 _. W* _( ?5 u4 p2 @( t
#* E# _. R+ L. i8 ~& y8 D
# For more information on CORS, please see: http://enable-cors.org/2 F$ |' A5 A- ] v. v
# Forked from this Gist: https://gist.github.com/michiel/10646403 p" [! Q# s2 Z* @9 [& `2 M
#
4 x2 H' p8 M0 f8 Q) w) m
* {* k% @* ^+ ], Q$ U) sset $cors '';
7 F8 l9 m# h! F9 e+ G4 eif ($http_origin ~ '^https?://(localhost|www\.yourdomain\.com|www\.yourotherdomain\.com)$') {
4 S$ I" C Z5 N1 @9 c set $cors 'true';! y4 O/ b8 q8 x' h0 H6 u1 E3 b
}: o) ~- N& H- b
" k/ k1 Z6 N0 J+ k4 }2 Z( z
if ($cors = 'true') {
0 H! K# X, H8 P# n6 O3 y add_header 'Access-Control-Allow-Origin' "$http_origin" always;, ]& v8 z: m7 J# c' v& @) O3 b
add_header 'Access-Control-Allow-Credentials' 'true' always;
# w& m) v1 @9 O, }, A4 n; B add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;; M+ p7 d) h* L7 [; _
add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With' always;
& Z* p- C A$ U2 a4 \' v6 q7 z # required to be able to read Authorization header in frontend
* r- Z1 T7 X. S" J #add_header 'Access-Control-Expose-Headers' 'Authorization' always;
$ [- \3 M3 o7 V- }: D4 l$ y7 q}& d% y0 \! R9 F6 n. S
/ O- u. N( o3 k5 r! Lif ($request_method = 'OPTIONS') {) V7 o! z/ H7 W
# Tell client that this pre-flight info is valid for 20 days
- c+ F5 O: g. K z: H1 o add_header 'Access-Control-Max-Age' 1728000;
6 q" `1 o; ^& y' Y add_header 'Content-Type' 'text/plain charset=UTF-8';" J" z( Y3 U; m2 `1 [. ~
add_header 'Content-Length' 0;
& v) l; a3 E, ^" V. b1 i return 204;
3 @; t6 L) L1 A3 Z& M& }# m( \+ [} https://gist.github.com/Stanback/7145487#file-nginx-conf 閮隢蝭靘:
! @6 _* O3 l+ l5 Z- i1 i$ H) xif ( $request_method !~ ^(GET|POST|HEAD|OPTIONS|PUT|PATCH|DELETE)$ ) { return 444;
: D; B/ G7 S' w* q% x" O}- J$ q, _+ p$ x; _+ `" ]
set $origin $http_origin; l( b! ~% \, W
if ($origin !~ '^https?://(subdom1|subdom2)\.yourdom\.zone$') {
4 T G# x7 i: L6 \1 S set $origin 'https://default.yourdom.zone';
$ b2 G4 `( |7 L1 V8 @, z+ p}
: t0 J2 V* N$ g( A# Cif ($request_method = 'OPTIONS') {
. J1 V# [/ u3 z2 z add_header 'Access-Control-Allow-Origin' "$origin" always;9 K3 u# s. x% \- `$ P% T
add_header 'Access-Control-Allow-Methods' 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always;
" O3 ]" r* o& B0 [4 Y add_header 'Access-Control-Allow-Headers' 'Content-Type, Accept, Authorization' always;
/ g2 j X2 x4 h; ^# c. x4 C+ Y add_header 'Access-Control-Allow-Credentials' 'true' always;
% K$ [8 S' [; |4 F2 v$ Z1 e add_header Access-Control-Max-Age 1728000; #20 days . U- n7 `2 I3 \0 `
add_header Content-Type 'text/plain charset=UTF-8'; N1 q N" ?1 ?1 Q( x
add_header Content-Length 0;
- E; H% {, e$ x: h H* q* { return 204;
1 }. k2 N: X6 v}. O$ c7 Y0 Z# A
if ($request_method ~ '(GET|POST|PATCH|PUT|DELETE)') {
' Q6 z' @4 i0 V' `0 g1 K) l5 V% a. \ add_header Access-Control-Allow-Origin "$origin" always;/ `/ e! q+ B9 o0 z3 g
add_header Access-Control-Allow-Methods 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always;( j! c) ~) g7 @+ ~$ S
add_header Access-Control-Allow-Headers 'Content-Type, Accept, Authorization' always;! P* D. @8 d2 x6 Q3 a9 K: Z( @
add_header Access-Control-Allow-Credentials true always;0 ~/ R5 r# {5 B5 V5 M' ^$ x
} Access-Control-Allow-Origin Multiple Origin Domains? 靘摮:# based on https://gist.github.com/4165271/
/ }* o0 u- Y/ t& w* W0 }4 B M+ r#
, C5 q- y4 a! R7 \1 `$ O# Slightly tighter CORS config for nginx
: \; I% I7 ?7 b#/ W- b* A/ \8 S0 r) o9 g! g3 |
# A modification of https://gist.github.com/1064640/ to include a white-list of URLs6 f: ]! F/ F% g
#
6 l; O K6 _) c# s, B; \# Despite the W3C guidance suggesting that a list of origins can be passed as part of0 T; V8 M" x: J2 j% K+ S
# Access-Control-Allow-Origin headers, several browsers (well, at least Firefox)
: X+ Q. |! ~1 z; T9 }# don't seem to play nicely with this.
8 ^# y; P$ ?* r! D) O3 E0 d+ `#
) H: x5 T) M) I6 B+ Y9 ?1 o o3 O# To avoid the use of 'Access-Control-Allow-Origin: *', use a simple-ish whitelisting Z: L, e) a2 J @% G. h; j0 p
# method to control access instead.
% K3 D! u0 I+ I4 }0 K% K( {#
3 g _; U+ O5 c4 m# NB: This relies on the use of the 'Origin' HTTP Header.
( Y9 |1 Z, }; H/ D0 i6 [. T5 C4 H# b
location / {. _3 b o4 y" A( H# [: [" d
+ Z' Y* x, y9 |5 @* F6 ]9 Z6 K/ s; v if ($http_origin ~* (^https?://([^/]+\.)*(domainone|domaintwo)\.com$)) {* E( {' H+ L0 V. G9 p' U
set $cors "true";
/ X: L0 Q6 l: E4 a/ Z }% _( y) { T' u# Z6 v
; {/ y; L7 X: ]) b # Nginx doesn't support nested If statements. This is where things get slightly nasty.7 P$ ]3 x/ y, g# U9 v5 ^; c/ S- `, k
# Determine the HTTP request method used3 }& Q# ~' p2 l/ {; Z
if ($request_method = 'OPTIONS') {
0 P4 i9 {8 l' M8 V- ]" \ set $cors "${cors}options";
. n( k% f3 ?* r2 ~" l. E }
1 l! b+ | N& ]# V& {8 C if ($request_method = 'GET') {/ D' ?2 X7 A3 ]5 p3 r
set $cors "${cors}get";
4 d, |; a8 l, h g }5 n# N7 R/ q% |
if ($request_method = 'POST') {2 Q' ?0 e9 r% [: x; _
set $cors "${cors}post";
& a* f+ d- a2 I3 L6 \ }
8 b2 {+ r# G3 _+ P# l3 n3 ]5 z$ R3 I5 F( t- R/ c, w' A8 ?
if ($cors = "true") {
. L& Z" J+ k- p. T # Catch all incase there's a request method we're not dealing with properly
. {, M0 L+ D5 d5 J# `$ e6 s) o1 ]4 }% ~ add_header 'Access-Control-Allow-Origin' "$http_origin";) ]5 ~9 i0 ?# O0 w* L$ J* U/ l! ]
} f& X6 y* Y% C% n$ z7 v) `
6 i! r, s% I: X! n! F" [3 g! v5 D if ($cors = "trueget") {; y1 h* Y5 G! D! \# |6 f' B; C1 m' Z, y
add_header 'Access-Control-Allow-Origin' "$http_origin";
# u* P3 q! F( ?1 G# } add_header 'Access-Control-Allow-Credentials' 'true';
5 p6 V4 }" P) W: b! t5 g# O add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';+ a5 p* q( r4 N0 T0 ^6 ]1 V: x O
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
& }( ^( d+ s ~4 V1 _ X) O# m) B }4 J+ i- u" d4 E$ q! T3 o6 G; ]
. ^% r. n; f( ^+ R5 v4 z) E
if ($cors = "trueoptions") {
3 D4 f4 j$ m5 }. S& l" F9 U add_header 'Access-Control-Allow-Origin' "$http_origin";6 w; z0 A0 u* U5 ?7 y
' E+ r; m+ F/ W1 n+ s #
+ S: X$ e3 P* I$ J2 d& u # Om nom nom cookies+ V: @& a! J7 E
#
+ R$ n' W/ |% K- n add_header 'Access-Control-Allow-Credentials' 'true';+ |2 r0 j+ x4 Y+ l
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
/ M0 C* i# L/ b, D2 \6 V$ S4 h I1 C% t; U
#% F" F; B) s) x* u8 Z% L
# Custom headers and headers various browsers *should* be OK with but aren't
7 \- A! \! A5 \1 S #2 z; F$ |* M2 @
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';: N% F! \: |) c. V0 M& U
! j# G8 ] T" z8 A: |6 S #
7 V" N, A9 `6 o/ M) ~; d2 M # Tell client that this pre-flight info is valid for 20 days( O& V/ }2 L4 }+ S6 G- Z3 [
#- _9 o5 a7 C! B5 e" \0 q
add_header 'Access-Control-Max-Age' 1728000;
0 K! V0 F, W8 u9 W/ I, H( c# l' { add_header 'Content-Type' 'text/plain charset=UTF-8';! d; X8 J8 |0 E7 }; E+ T3 C; z
add_header 'Content-Length' 0;
m" o2 j. J. C0 q+ {4 m$ q& k# [ return 204;$ F: [! ^' r2 ~: _6 k. V$ n
}
; P S- {; Y# n& F8 P) p
: m: ]: \- |' h2 O- K if ($cors = "truepost") {
+ s. o/ _: I- v4 Q9 ?; D add_header 'Access-Control-Allow-Origin' "$http_origin";8 e+ m$ A7 q5 S* h% Y0 a: e4 m( _
add_header 'Access-Control-Allow-Credentials' 'true';- L+ H; [5 p8 D+ E
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';) d# z+ N0 \- H1 C$ Y! ~
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
: A2 y) v- d! d) \/ u }0 Z; t9 e8 i v" ^8 n3 S
* R* p8 }: J- e. M( u" j}
" r, l# d+ b( h7 S" d: Q
" ~7 m p4 X- g) H4 U/ M |
|