2013-04-26 6 views
9

Staram się, aby Flask poprawnie obsługiwał skrypty cross-site. Wziąłem tutaj fragment kodu dekoratora crossdomaina: http://flask.pocoo.org/snippets/56/Python Flask cross site HTTP POST - nie działa dla konkretnych dozwolonych początków

W poniższym kodzie wstawiłem fragment kodu dekoratora i podstawowy serwer kolb.

Zadzwonię do dekoratora z nagłówkami = "Content-Type", ponieważ w przeciwnym razie otrzymywałem "Pole nagłówka żądania Content-Type nie jest dozwolone przez Access-Control-Allow-Headers." w przeglądarce.

Oto moje pytanie: Tak jak jest, poniższy kod działa. Ale gdy chcę ograniczać się tylko do określonego serwera tak:

@crossdomain(origin='myserver.com', headers='Content-Type') 

pojawia się błąd przeglądarce

„Pochodzenie http://myserver.com nie jest dozwolone przez Access-Control-Allow-Origin”.

Nie mogę sprawić, żeby działało dla niczego innego niż origin = '*'.

Czy ktoś ma jakieś pomysły?

Oto kompletny kod:

from datetime import timedelta 
from flask import make_response, request, current_app, Flask, jsonify 
from functools import update_wrapper 

def crossdomain(origin=None, methods=None, headers=None, 
      max_age=21600, attach_to_all=True, 
      automatic_options=True): 
    if methods is not None: 
     methods = ', '.join(sorted(x.upper() for x in methods)) 
    if headers is not None and not isinstance(headers, basestring): 
     headers = ', '.join(x.upper() for x in headers) 
    if not isinstance(origin, basestring): 
     origin = ', '.join(origin) 
    if isinstance(max_age, timedelta): 
     max_age = max_age.total_seconds() 

    def get_methods(): 
     if methods is not None: 
      return methods 

     options_resp = current_app.make_default_options_response() 
     return options_resp.headers['allow'] 

    def decorator(f): 
     def wrapped_function(*args, **kwargs): 
      if automatic_options and request.method == 'OPTIONS': 
      resp = current_app.make_default_options_response() 
      else: 
       resp = make_response(f(*args, **kwargs)) 
      if not attach_to_all and request.method != 'OPTIONS': 
       return resp 

      h = resp.headers 

      h['Access-Control-Allow-Origin'] = origin 
      h['Access-Control-Allow-Methods'] = get_methods() 
      h['Access-Control-Max-Age'] = str(max_age) 
      if headers is not None: 
       h['Access-Control-Allow-Headers'] = headers 
      return resp 

     f.provide_automatic_options = False 
     return update_wrapper(wrapped_function, f) 
    return decorator 

app = Flask(__name__) 

@app.route('/my_service', methods=['POST', 'OPTIONS']) 
@crossdomain(origin='*', headers='Content-Type') 
def my_service(): 
    return jsonify(foo='cross domain ftw') 

if __name__ == '__main__': 
    app.run(host="0.0.0.0", port=8080, debug=True) 

Dla porównania moja wersja Pythona 2.7.2 wersja kolby 0.7.2

Odpowiedz

2

prostu próbowałem tego samego kodu Pythona w wersji 2.7.3 i Wersja kolby 0.8.

Z tych wersjach, nie jest on z

@crossdomain(origin='myserver.com', headers='Content-Type') 

ale działa z

@crossdomain(origin='http://myserver.com', headers='Content-Type') 

Być może po prostu nie działa z kolbą 0.7.2? (pomimo tego, co mówi na stronie z informacjami).


EDIT: Po zagraniu z tym dużo więcej (i modernizacji do kolby 0,9) wydaje się, że prawdziwym problemem (lub jeszcze inny problem) może być związany z posiadania wielu dozwolony początki w formie listy. Innymi słowy, używając powyższego kodu:

@crossdomain(origin=['http://myserver.com', 'http://myserver2.com'], headers='Content-Type') 

nie działa.

Aby naprawić ten problem, poprawiłem dekorator. Zobacz kod: http://chopapp.com/#351l7gc3

Ten kod zwraca tylko domenę witryny, która zadaje zapytanie, jeśli znajduje się na liście. Kinda ekscentryczne, ale przynajmniej dla mnie problem został rozwiązany :)

+0

mogę zobaczyć kod – martriay

+0

to tam, ale z jakiegoś powodu zajmuje dużo czasu, aby załadować. – Nate

+0

Powtórz kod: zauważ, że request.headers ['Origin'] może być Brak, a operator 'in' nie może przyjąć None jako lewego argumentu. W przeciwnym razie, dzięki :-) –

0

Python bardzo się stara, aby nie narażać się na ataki typu cross-site scripting.

Jedną z poprawek jest wpisywanie, a po otrzymaniu żądań trafienie na ten sam serwer, na którym uruchomiony jest skrypt z kolbą.Pobieranie JSON z odległych serwerów zdefiniowanych w łańcuchach to i tak ryzykowny biznes.

udało mi się go naprawić przez przeglądarkę pozwalając utrzymać się na tym samym serwerze, na przykład:

$('a#calculate').bind('click', function() { 
    $.getJSON('/_add_numbers', { 
    a: $('input[name="a"]').val(), 
    b: $('input[name="b"]').val() 
    }, function(data) { 
    $("#result").text(data.request); 
    }); 
    return false; 
}); 

Wskazówki jak metoda getJSON przepuszcza się /_add_numbers. To komunikuje się z przeglądarką, aby pozostać na tym samym hoście i szukać tej strony. Wtedy przeglądarka jest szczęśliwy i bezpieczny my trwamy na tym samym hoście, a ty nigdy nie pojawia się błąd:

Origin http://myserver.com is not allowed by Access-Control-Allow-Origin 
Powiązane problemy