简体   繁体   English

Rails在登录后设计重定向

[英]Rails Devise redirect after login

I am using Devise with Rails for my user login. 我正在使用Devise with Rails来登录我的用户。 It all works great, however, i am unable to get a specific redirection working. 这一切都很好,但是,我无法获得特定的重定向工作。

I am new to rails so the method in which i am doing things may not be correct. 我是rails的新手,所以我做事的方法可能不正确。

Essentially, with an example, i am allowing users to like a post. 基本上,举个例子,我允许用户喜欢帖子。 However, they need to be signed in to do so. 但是,他们需要登录才能这样做。 I have created an action in my controller called 'like' and the controller has the devise filter 我在我的控制器中创建了一个名为'like'的动作,控制器有一个设计过滤器

before_filter :authenticate_user!, :except => [:index, :show]

entered thereby the sign in page is being shown. 因此输入了登录页面。 Once the user signs in i want to redirect them back to the post which they have liked with the 'like' action having been called. 一旦用户登录,我想将他们重新定向回他们所喜欢的帖子,并且已经调用了“喜欢”的动作。

my controller looks like 我的控制器看起来像

def like

  @post = Post.find(params[:id]) 
  @like = Like.new;
  @like.user_id = current_user.id;
  @like.post_id = params[:id];
  respond_to do |format|
    if @like.save
      format.html { redirect_to @post, notice: 'You have like this post' }
      format.json { head :no_content }
    else 
      format.html { redirect_to @post, notice: 'Sorry you like was not saved  } 
      format.json { render json: @post.errors, status: :unprocessable_entity }
    end
  end  
end 

Naturally i cannot hard code the path using after_sign_in_path_for 当然,我无法使用after_sign_in_path_for对路径进行硬编码

def after_sign_in_path_for(resource)    
  #path to somewhere
end

But i have read that i can use a session variable and perhaps call that in the above code. 但我已经读过,我可以使用会话变量,并可能在上面的代码中调用它。 In which part of Rails could i write the session variable, as it would be too late in the controller action (as devise takes over before it hits the like action) and i cannot see how to set it in the view. 在Rails的哪一部分我可以编写会话变量,因为它在控制器动作中太迟了(因为设计在它执行类似动作之前接管)并且我无法看到如何在视图中设置它。

Also my link looks like 我的链接看起来像

<%= link_to "Like", {:controller => :posts, :action => :like, :id => @post.id}, {:method => :post } %> |

PS the redirection when using creating a new 'post' works ok ie the user signs in and are redirected to the new post view. PS使用创建新“帖子”时的重定向工作正常,即用户登录并重定向到新的帖子视图。

Any help and tips would be greatly appreciated. 任何帮助和提示将不胜感激。

Thanks 谢谢

You are experiencing this because like action is specifically designed for POST. 您遇到了这种情况,因为类似的操作是专为POST设计的。 Therefore, you should make sure that user is signed in before you POST to that URL, and doing it with session is tricky: 因此,在POST到该URL 之前 ,应确保用户已登录,并且使用会话执行此操作非常棘手:

  • You'd have to unprotect like method by excluding it from before_filter 您必须通过从before_filter排除它来取消保护类似方法
  • Then check manually if user_signed_in? 然后手动检查user_signed_in? (mind you this is a helper method), (请注意,这是一个辅助方法),
  • Then (if user is not signed in), stash what you are liking in session and redirect to sign in page with return URL 然后,(如果用户没有登录),藏在你会话中喜欢什么,并重定向到页面返回URL登录
  • Upon user visiting this return URL (it will be a GET and not a POST ), you would have to look up the session info and do what original Like was supposed to do (but by then user will be signed in). 当用户访问此返回URL(它将是GET而不是POST )时,您将不得不查找会话信息并执行原始的Like应该执行的操作(但是当时用户将登录)。

Seeing that all of this dance will end with a GET request, why not make Like action work on GET requests as well as pass parameters in the Query String in the first place? 看到所有这些舞蹈都以GET请求结束,为什么不首先让Like动作处理GET请求以及在查询字符串中传递参数? It will require 0 code changes and it will not expose you to a security threat since Like is protected by before_filter. 这将需要0代码更改,它不会让您暴露于安全威胁,因为Like受before_filter保护。 You would just have to make sure that your Like links aren't followed by search engines by using rel="nofollow" on your <a> tags. 您只需要在<a>标签上使用rel =“nofollow”确保搜索引擎不会跟随您的Like链接。

For a related discussion, see redirect_to using POST in rails . 有关相关讨论,请参阅使用rails中的redirect_to There, one of the suggestions is to build and submit a form on the client via JavaScript. 在那里,其中一个建议是通过JavaScript在客户端上构建和提交表单。 That would have to happen on that return URL view once user has authenticated. 一旦用户进行了身份验证,就必须在该返回URL视图上进行此操作。 This might be the best compromise if you object to having your like action exposed as GET (which violates REST principles) 如果你反对将你喜欢的行为暴露为GET(违反REST原则),这可能是最好的妥协

this is easy to fix: 这很容易解决:

go in application controller: 进入应用程序控制器:

 # after login redirect
 after_filter :store_location

 def store_location
   # previous url save when its not a admin or user url
   session[:previous_url] = request.fullpath unless request.fullpath =~ /\/users/ || request.fullpath =~ /\/admin/ || request.fullpath =~ /\/admin\/login/ || 
   request.fullpath =~ /\/login/
 end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM