rails 4- 401 Unauthorized error handling

2019-08-18 15:07发布

问题:

I am making a simple quora like question answer site where login is using devise. I was trying to render form in the question index itself using ajax. Everything seems to work fine except that when no user is logged in The server says 401 unauthorised Completed and nothing seems to happen. Console Response:

Started GET "/questions/new" for 127.0.0.1 at 2017-07-18 18:30:54 +0530 Processing by QuestionsController#new as JS Completed 401 Unauthorized in 1ms (ActiveRecord: 0.0ms)

controller: def new @question = Question.new(:user=>current_user) respond_to do |format| format.js {} end end

I know this because of the before_action :authenticate_user! in the questions controller. Chrome console in Network response also says "You need to sign in or Sign Up before continuing."

Also, i tried byebug but came to know that the flow never reaches the new action.

I want to know how to handle this error. To either show that I need to sign in or signup as a notice or alert at top of the page or redirect to the sign in page.

Edit: I am using remote: true for calling ajax. in New Question link on the index page.

回答1:

This is easiest to deal with in the controller. Create a method called "check_user":

def check_user
  return if user_signed_in?
  redirect_to new_user_session_path, error: 'You must log on to view this part of the site'
end

Then we can decide what pages we want to check for the user for each controller. If you want to limit every question page for users, then simply do:

class QuestionsController < ApplicationController
  before_action :check_user

  ...
end

This will perform the method before every Questions Controller action. Alternatively, if you want anyone to be able to view say the index and show pages but not any others:

before_action :check_user, except: [:index, :show]


回答2:

@Mark let you know how you can implement authorization on controller, but I see you're using json response here so server redirection probably is not good choice here.

def new
  @question = Question.new(:user=>current_user)
  respond_to do |format|
    format.js {
      body: {}, status: authorized? ? 200 : 401
    }
  end
end

Then, based on that status you're receiving on client side, you can easily do redirection.