Hoe stuur ik CORS headers met Devise als de gebruiker niet geautoriseerd is (401 antwoord)

Ik ben bezig met een app, waarbij de server en de api-consumerende client zich onder verschillende domeinen bevinden, dus ik zou graag CORS . Om dit te doen, moet ik overeenkomstige http-headers instellen in de serverreactie:

def cors_set_access_control_headers
  headers['Access-Control-Allow-Origin'] = 'http://localhost'
  headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS'
  headers['Access-Control-Allow-Headers'] = '*, X-Requested-With, X-Prototype-Version, X-CSRF-Token, Content-Type'
  headers['Access-Control-Max-Age'] = "1728000"
end

Deze methode wordt gebruikt als een before_filter in ApplicationController .

Voor sommige bronnen moet de gebruiker worden geverifieerd en geautoriseerd. Verzoeken worden gedaan via XHR/Ajax. Dus als de gebruiker niet is geverifieerd, stuurt Devise een 401-antwoord naar de client, in plaats van door te sturen naar een bord op pagina. Maar het filter voor het instellen van de CORS-headers wordt niet gebruikt voor dat antwoord. Het 401-antwoord wordt dus niet naar de client verzonden. Ik wil het 401-antwoord in de client vangen en gebruiken.

Momenteel gebruik ik een tijdelijke oplossing door de Devise-verificatiemethoden niet te gebruiken, maar een aangepast auth-fragment:

def authenticate_cors_user
  if request.xhr? && !user_signed_in?
    error = { :error => "You must be logged in." }
    render params[:format].to_sym => error, :status => 401
  end
end

Dit is ook ingesteld als een before_filter in ApplicationController . Op deze manier wordt het filter voor het instellen van CORS-headers geactiveerd en werkt alles goed.

Ik gebruik liever het standaardgedrag van Devise, maar de CORS-headers moeten worden ingesteld in het 401-antwoord. Hoe doe je dit? Moet ik daarvoor warden configureren?

Hoe kunnen de CORS-headers worden ingesteld op het 401-antwoord gegenereerd door Devise in plaats van mijn eigen reactie te creëren?

18
Toch heb ik daar geen oplossing voor. Om wat meer context te geven, bekijk mijn blogpost over hoe ik dit gebruik: nils-blum-oeste.net/…
toegevoegd de auteur Nils Blum-Oeste, de bron

2 antwoord

Ik heb de rack-cors edelsteen met succes https://github.com/cyu/rack-cors met succes gebruikt en mijn ervaring uiteengezet op mijn blog .

Punchline: geef de middleware-order op zodat de cors-handler voor de warden staat:

config.middleware.insert_before Warden::Manager, Rack::Cors
21
toegevoegd
Je aanpak werkt fantastisch, bedankt! Vreemd genoeg kostte het echter enige tijd en wat aanvullend onderzoek om te realiseren dat ik echt maar één regel code in configuratie hoef te wijzigen om Devise en rack-cors te maken om samenwerken.
toegevoegd de auteur denis.peplin, de bron
Hey @ digger69. Had u problemen met andere uitzonderingen? Bijvoorbeeld: als ik een uitzondering in mijn actie def index gooi; raise 'error'; end - Rails retourneert de CORS-headers (rack-cors) niet. Werkt het voor jou?
toegevoegd de auteur Pablo Cantero, de bron
PS: je zou ook config.middleware.insert 0, Rack :: Cors kunnen gebruiken om te garanderen dat Rack :: Cors vóór elke andere mogelijke middleware wordt ingevoegd.
toegevoegd de auteur Pablo Cantero, de bron

We hadden over het algemeen een hekel aan CORS-headers. Wij geven er de voorkeur aan om HAProxy te gebruiken voor omleidingen.

Met HAProxy kunt u alle verzoeken die naar website.com/api/ komen, instellen om intern doorgestuurd te worden naar uw rails-machine.

frontend main *:80
  acl api      path_beg  -i /api
  acl app      path_beg  -i /app
backend app_backend
  reqrep    ^([^\ ]*)\ /app/(.*)  \1\ /\2
  balance   roundrobin
  server    app_files smartphoneapp.localhost:8000
backend api_backend
  reqrep    ^([^\ ]*)\ /api/(.*)  \1\ /\2
  balance   roundrobin
  server    app_api localhost:3000
0
toegevoegd
Bekijk dit artikel: tsheffler.com/blog/?p=428
toegevoegd de auteur Hendrik, de bron
CORS kan worden omzeild met behulp van een proxy, zeker. Maar toch moet er een manier zijn om dit goed aan te pakken met Devise/Warden, denk ik.
toegevoegd de auteur Nils Blum-Oeste, de bron