隞乩gist.github.com舀reverse proxied APIs蝭靘:% O: A7 T1 \. L9 e9 b- p9 @. v
. u, R/ R- U: H/ |1 X) M/ @7 @
( F: h5 |; w0 T" a$ o) y2 D# {# CORS header support+ f4 H2 C. B( x" u/ e
#
6 O% ]1 C8 O5 B7 _, m# One way to use this is by placing it into a file called "cors_support"
: X- k5 z, V- }! d# g" ~/ b# under your Nginx configuration directory and placing the following
% [ o5 `& ]9 x, P# statement inside your **location** block(s):
- H8 q. f( G( M! ^#
+ K" m9 U4 H4 L/ ~* _0 ^# include cors_support;4 w+ C4 z. ] h0 Y+ X
#+ H2 ~0 n; i1 I- a) ]; n( s
# As of Nginx 1.7.5, add_header supports an "always" parameter which
: Q2 W4 N( B) n; B" V+ I$ X# allows CORS to work if the backend returns 4xx or 5xx status code.
/ D2 U! ?$ M/ j) z4 q! x#' H. u2 B6 P3 s9 m! s
# For more information on CORS, please see: http://enable-cors.org/0 f# r$ ~7 x( C. {/ {4 A
# Forked from this Gist: https://gist.github.com/michiel/1064640* d% |4 d8 a h! z2 y" W, V
#
9 w' Q+ q; [$ j6 L! ~; ]! z
- _' {. i% X: L! C eset $cors '';
0 x% M( l' a+ J3 ~! ]4 u N. wif ($http_origin ~ '^https?://(localhost|www\.yourdomain\.com|www\.yourotherdomain\.com)$') {4 b& H3 v) w1 S3 W5 c, T; a5 ^6 C
set $cors 'true';# Z" X$ Q4 i0 {8 }3 m$ N
}
- {) a5 v3 V6 q9 }3 Z8 v4 o" p/ o8 v: d8 o2 `
if ($cors = 'true') {! t/ o& \) ~! }
add_header 'Access-Control-Allow-Origin' "$http_origin" always;* U6 ]. N) E9 L
add_header 'Access-Control-Allow-Credentials' 'true' always;
) P2 T) O/ E# r, g! \$ Q add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;, Y5 `- k7 a5 h' T& y+ x
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;
! X. f8 f; n9 v R9 [- i' n # required to be able to read Authorization header in frontend3 U |$ [* x; v; [3 S
#add_header 'Access-Control-Expose-Headers' 'Authorization' always;
* s( u1 C. p% J}
+ p, l. S7 s3 Y8 ]
6 @% v/ ?& v$ Z1 I: ^if ($request_method = 'OPTIONS') {' T& c2 m' v/ E. _/ g0 G, H+ N
# Tell client that this pre-flight info is valid for 20 days
( G$ b: x5 W6 o add_header 'Access-Control-Max-Age' 1728000;
- m A' Q! `7 j) c( o add_header 'Content-Type' 'text/plain charset=UTF-8';8 w0 s, |0 P0 `# H0 L: k
add_header 'Content-Length' 0;
# ^+ t4 r% N- Z3 m return 204;
5 S7 M2 Z- ?2 o$ L6 F" q8 W3 D} https://gist.github.com/Stanback/7145487#file-nginx-conf 閮隢蝭靘:; M5 C% V8 {* D0 D, j- i7 N0 V
if ( $request_method !~ ^(GET|POST|HEAD|OPTIONS|PUT|PATCH|DELETE)$ ) { return 444;
2 R1 X5 a) K) d: U2 |: {}
6 d9 G! B3 [5 P9 Q& j. ]0 l$ Xset $origin $http_origin;
4 x# Y m) T: n; ?5 ^if ($origin !~ '^https?://(subdom1|subdom2)\.yourdom\.zone$') {2 u* R% m( v) l- [% G! l
set $origin 'https://default.yourdom.zone';9 e- G; {: c& ?
}; @. K4 ]. Y1 |4 ^" |% F; C7 g7 x8 \
if ($request_method = 'OPTIONS') {
* s3 y) j2 a5 c9 _ add_header 'Access-Control-Allow-Origin' "$origin" always;, ^# z7 P$ c" c
add_header 'Access-Control-Allow-Methods' 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always;9 ^- u* X8 L7 l1 p4 N3 o9 l
add_header 'Access-Control-Allow-Headers' 'Content-Type, Accept, Authorization' always;
' ^0 ^& u; z- f& i$ L/ d2 V add_header 'Access-Control-Allow-Credentials' 'true' always;
' }: @0 b+ A7 S4 m+ W! P8 S4 O$ @ add_header Access-Control-Max-Age 1728000; #20 days
2 W- F1 p3 ^4 J' e! Y add_header Content-Type 'text/plain charset=UTF-8';
6 ^5 t3 F# ^$ e4 L add_header Content-Length 0;2 G' Y$ `, L- ^
return 204;
0 h$ h, `* u6 v; m/ T& [! Y}
, i6 m4 n& `' r$ Dif ($request_method ~ '(GET|POST|PATCH|PUT|DELETE)') {8 O8 m7 L/ q2 I5 p1 _# S$ Q! B
add_header Access-Control-Allow-Origin "$origin" always;
' `* E. v) ]) _3 k add_header Access-Control-Allow-Methods 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always;
: w4 F4 e0 L9 d s3 V* T4 f i) | add_header Access-Control-Allow-Headers 'Content-Type, Accept, Authorization' always;; ~- G; _) ~) ~
add_header Access-Control-Allow-Credentials true always;8 Q. \4 F& P& U
} Access-Control-Allow-Origin Multiple Origin Domains? 靘摮:# based on https://gist.github.com/4165271/( `0 [+ J% d( ^! Q8 L& |" O+ u
#
8 G: C' u6 Y% v# r# Slightly tighter CORS config for nginx
+ ]1 V6 _# a2 s5 \' g1 C5 {#
: S" \! O7 S2 I: P! v' K* n# A modification of https://gist.github.com/1064640/ to include a white-list of URLs
1 r$ X; m3 `& h4 v#
0 e- x7 a# P; g1 d: o: P/ m# Despite the W3C guidance suggesting that a list of origins can be passed as part of
* x2 N6 W. U( B6 R6 ^9 Q/ R" ?) ^# Access-Control-Allow-Origin headers, several browsers (well, at least Firefox)
+ w+ S( ~' g; I7 }: R" |) y# don't seem to play nicely with this.
; p1 @, c$ v' i+ ^ R2 s8 S9 c#
/ q& k/ [+ o6 w* |2 l& v* ~) |# To avoid the use of 'Access-Control-Allow-Origin: *', use a simple-ish whitelisting
6 e o/ F) ?3 S" `# method to control access instead.
& o6 x" w# {* W& c#
3 u# n/ J5 e0 i, ~6 H5 D# NB: This relies on the use of the 'Origin' HTTP Header.
* H1 T$ N* T. {+ |( m. c" E# Z9 P5 {% z/ e% p
location / {- K. `: e n3 u
/ G* b) V" X5 Y$ c- K# |% B if ($http_origin ~* (^https?://([^/]+\.)*(domainone|domaintwo)\.com$)) {
: S2 @) ]" C8 l2 f2 J3 N set $cors "true";
0 m5 ^. _! Q( J" V7 x- v$ l }
5 x5 X" S" R% e( i
' C0 m9 w7 m4 _ # Nginx doesn't support nested If statements. This is where things get slightly nasty.: J3 `0 d+ C) x. U6 q) @/ ?
# Determine the HTTP request method used
, ~. R# t5 Q" h+ p if ($request_method = 'OPTIONS') {8 U [; \ v" \! _* |
set $cors "${cors}options";
' L' j0 w1 F9 l3 ~$ O- J4 f }) R5 Y7 b6 ^% X" l+ x
if ($request_method = 'GET') {
) Q; G) f/ C% N set $cors "${cors}get";
" x D, L' g( \$ p" I C }; U5 y; v) H) \
if ($request_method = 'POST') {
0 p3 w3 J6 {* e/ v set $cors "${cors}post";. |8 t) D6 `; _9 {
}$ B( M& \; h# i" w- H/ W& s9 R
! C1 }; J7 e0 I6 D! {
if ($cors = "true") {8 E( b% q7 L. ^- L7 h# D
# Catch all incase there's a request method we're not dealing with properly
) u8 _6 u: B& ` add_header 'Access-Control-Allow-Origin' "$http_origin";$ X5 f& m1 c( _( l3 j* B7 m
}9 I1 f* ^# w& p7 D$ g# y7 n- d
; o8 H" g% j) |; S7 [; E if ($cors = "trueget") {
) }) _9 A1 N1 K: _ add_header 'Access-Control-Allow-Origin' "$http_origin";
* @- {) a. e% @7 I5 F add_header 'Access-Control-Allow-Credentials' 'true';* E) ~6 ]4 {' F
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';, L8 Y0 p: K* i7 f
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';2 B# Z6 a) Z/ A, `+ j8 V* q: [; K
}) K& J' t3 m! |9 O
5 E4 ^0 v8 j5 E: J0 `( T+ E1 m if ($cors = "trueoptions") {& z, J% _! x" ^+ ]( B% R' i* p' M# U
add_header 'Access-Control-Allow-Origin' "$http_origin";
6 r0 f4 B. o2 K: O4 H
# |3 s g8 z! |- ^4 M, u- E #4 S& |! X; Z2 K4 B$ \8 [
# Om nom nom cookies0 v B" O. K- ~; |9 u$ z# O
#
) _# w6 ^! D' O0 E. o3 }4 c1 ? add_header 'Access-Control-Allow-Credentials' 'true';
+ d$ k+ H, h1 J( j; |3 ^ add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
, Q8 ~+ E) h! n1 G: I) H/ J) E G% H# c3 s1 e
#
( |8 U0 X4 k2 p4 q+ K # Custom headers and headers various browsers *should* be OK with but aren't
0 m+ Z% @1 |8 j/ \ #6 [! d: @) o3 O) G6 R* r9 l! p) F
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'; V/ o6 X) o$ F# \3 b! o
* v7 b) m" ?+ c. d& `' o8 { #
9 f( X9 i1 @5 _+ T& H/ ` # Tell client that this pre-flight info is valid for 20 days
0 {4 X8 F" q+ y) V1 w5 R #
& r$ M: M2 a4 x5 U( k' v( j add_header 'Access-Control-Max-Age' 1728000;1 u+ ?" P8 T. Y
add_header 'Content-Type' 'text/plain charset=UTF-8';
* M2 D, a# t6 P- S0 G- X1 K! Z+ s add_header 'Content-Length' 0;
) f# K& Q: m# K0 V ` k1 E' ` return 204;
5 q. C8 _- n% e: _8 v" F: f) Q! h }) n1 T) z3 S, B9 ]: G. f0 b
# b# ^6 v& N# o1 a" ~" \
if ($cors = "truepost") {
1 ^+ S' D- ?) E$ s, Q2 L add_header 'Access-Control-Allow-Origin' "$http_origin";! S2 j4 {$ o7 M6 R& r
add_header 'Access-Control-Allow-Credentials' 'true';3 n6 B5 K1 ~3 C& F2 y8 X9 j; {
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
- M1 y7 U8 b( @' r; K add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
$ G7 v9 \5 H6 I6 q& i u% |) y$ f }1 a0 l5 |8 e K; I& D' G- c
1 ~5 d" J5 ]0 o. m; n, Y}
& e9 J7 J2 z- f, h4 l9 J) X
8 B$ G* t) {3 ` |
|