2017-10-07 1 views
1

J'ai une page de connexion sur laquelle l'authentification peut aboutir ou non. Voici la page new.html.erb:Modification de l'URL du navigateur après l'échec de la publication http

<%=form_with scope: :session, url: sessions_path, local: true, html: {class: "login-form"} do |f| %> 
    <%= f.label :email, t("session.new.email") %> 
    <%= f.email_field :email %> 

    <%= f.label :password, t("session.new.password") %> 
    <%= f.password_field :password %> 

    <%= f.submit t('session.new.login'), class: "submit" %> 
<% end %> 

Il est associé à un sessions_controller.rb, qui est la suivante:

class SessionsController < ApplicationController 

    def create 
    # Find the user with the matching email 
    user = User.find_by(email: params[:session][:email].downcase) 

    # Check the user exists in DB and that the provided password matches 
    if user && user.authenticate(params[:session][:password]) 
     # Log the user through the session helper 
     log_in user 
     # Redirect to the hive 
     redirect_to ideas_path 
    else 
     # The authentication failed. Display an error message 
     flash.now[:error] = I18n.t('session.new.invalid_credentials') 
     # The render is done to reinitiate the page 
     render :new 
    end 
    end 
end 

Dans mon routes.rb, je viens à cette fin:

resources :sessions 

Lors de l'exécution rails routes, j'ai les itinéraires déclarés suivants:

Routes

Maintenant, mon problème est sur l'échec de la connexion. Dans mon contrôleur, dans ce cas, j'ajoute un message dans les messages flash puis rends la même page new.html.erb. Mais dans le navigateur, la demande de connexion POST a été envoyée sur l'url /sessions. Le problème est l'URL actuelle sur mon navigateur devient /sessions au lieu de rester sur /sessions/new. C'est comme si la requête POST avait changé l'URL dans mon navigateur. Mais il s'agit en fait d'une requête AJAX, n'est-ce pas?

J'ai trouvé ce blog post qui se demande la même chose au sujet de ce phénomène (je ne suis pas l'auteur)

J'ai trouvé une solution, mais je préfère éviter de l'utiliser et de comprendre le bevahior. Si je remplace mes itinéraires par ce qui suit, cela fonctionne:

get '/login', to: 'sessions#new' 
post '/login', to: 'sessions#create' 

Je peux comprendre pourquoi cela fonctionne: le get et l'url de poste sont les mêmes, de sorte que le navigateur ne change pas son URL.

Avez-vous une idée?

EDIT:

j'ai finalement trouvé une solution. Je ne suis pas sûr que ce soit la "voie des rails", mais cela fonctionne comme prévu. Je viens de changer le contrôleur pour faire une redirection vers la même page, avec une demande flash pour transmettre la connexion échouent informations:

def create 
    # Find the user with the matching email 
    user = User.find_by(email: params[:session][:email].downcase) 

    # Check the user exists in DB and that the provided password matches 
    if user && user.authenticate(params[:session][:password]) 
    # Log the user through the session helper 
    log_in user 
    # Redirect to the hive 
    redirect_to ideas_path 
    else 
    # The authentication failed. Display an error message through a flash 
    # message after redirect to the same page 
    redirect_to new_session_path, alert: I18n.t('session.new.invalid_credentials') 
    end 
end 

Répondre

2

Lorsque le formulaire est soumis le navigateur effectue une HTTP régulière POST requsest aux/sessions point final. Pas d'AJAX là.

La façon dont vos routes sont configurées Cette requête POST sera gérée par votre session # create action.

Notez le code ici. Vous verrez que le chemin heureux (connexion réussie) appelle redirect_to. En cas d'erreur de connexion, le contrôleur appelle render. La différence est que dans le premier cas, la réponse est une redirection 302 que le navigateur suit. C'est pourquoi vous voyez l'URL changer dans le navigateur. Dans le second cas, la réponse est juste 200 OK avec un tas de HTML pour le navigateur à rendre. L'URL ne changera pas car le navigateur n'a pas été invité à naviguer ailleurs.

Voici un extensive explanation of how redirects work dans le navigateur au cas où vous êtes intéressé.

+0

Merci pour votre réponse et le document associé. Il y a un point qui me manque: Pourquoi l'URL de mon navigateur change-t-elle lorsque je soumets une requête POST? Je pensais que cela ne devrait être le cas que sur les requêtes GET. En outre, quelle est la bonne approche avec RoR pour mon cas d'utilisation? –

+1

Été essayer de trouver une documentation appropriée sur ce qui pourrait l'expliquer mieux que moi, mais pas de chance. Le navigateur visite '/ sessions/new'. Ensuite, vous soumettez le formulaire, donc la dernière URL connue du navigateur est '/ sessions'. C'est la "ressource" qui a été demandée au serveur. Le serveur répond, et puisqu'il ne redirige pas, le navigateur utilisera cette URL. Ouvrez les outils de développement dans votre navigateur et vérifiez la réponse du serveur. L'URL de réponse est '/ sessions', n'est-ce pas? J'espère que cela a du sens:/ – gkats

+0

Oui, votre réponse m'a aidé à comprendre. Maintenant, je dois juste comprendre comment utiliser Rails correctement afin que je puisse atteindre mon objectif :) –