Генерация нового маршрута для «публичной» ссылки из приложения Rails - PullRequest
0 голосов
/ 17 ноября 2018

Я пытаюсь создать «общедоступную» ссылку, которая дает кому-то доступ к определенной странице моего приложения без необходимости входа / авторизации.

Я немного растерялся, чтобы найти лучший способ решить эту проблему, поэтому обращаюсь за советом.

Для начала я добавил random_id в таблицу объекта, вокруг которого строю ссылку (Captable).

С чем я сейчас борюсь: должен ли я создать совершенно новый контроллер (например, PublicCaptableController) и просмотреть эту общедоступную ссылку, чтобы я мог контролировать то, что увидит этот «публичный зритель»? Или есть какой-нибудь более простой способ создания нового представления с использованием моего существующего CaptablesController, который обслуживает выбранный набор информации, которой я могу управлять с помощью существующего контроллера?

Одна из моих идей заключалась в том, чтобы отредактировать application_controller.rb следующим образом:

before_action :authenticate_user!, unless: -> params[:random_id].present?

Но это похоже на довольно большую угрозу безопасности. Как я могу сделать это простым, но более эффективным / безопасным способом?

Благодарен за любое руководство / помощь!

Вот мой routes.rb файл.

Rails.application.routes.draw do

  devise_for :users
  get '/landing', :to => redirect('/landing.html')
  root 'companies#index'
  post "companies/switch_current_company_context" => "companies#switch_current_company_context"

  resources :companies do
    resources :shareholders
    resources :captables do
      post :subscribe_to_captable
      resources :events do
        post :lock_event
        post :unlock_event
        resources :transactions
      end
    end
  end
end

фрагмент из CaptablesController

class CaptablesController < ApplicationController
  before_action :set_company
  before_action :set_captable, only: [:show, :edit, :update, :destroy]

  def index
    @captables = @company.captables
  end

  def show
    @captable = Captable.find(params[:id])
  end

Фрагмент из ApplicationController

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception, unless: -> { request.format.json? }
  before_action :authenticate_user!

  def after_sign_in_path_for(resource_or_scope)
    # Set a default current company scope for a use after signing in
    session[:current_company] = current_user.companies.first.id unless current_user.companies.empty?
    puts session[:current_company]
    companies_path

  end

end

1 Ответ

0 голосов
/ 17 ноября 2018

Вы можете добавить простой маркер доступа к модели и использовать его для обхода авторизации / аутентификации при прохождении через строку запроса.

Сначала добавьте столбец в таблицу:

rails g migration add_access_token_to_captables access_token:string
rails g migrate

Тогда вам нужна подходящая псевдослучайная строка токена. Ruby Stdlib имеет защищенный модуль SecureRandom.

SecureRandom.hex(10) #=> "52750b30ffbc7de3b362"

Позволяет настроить обратный вызов модели для создания случайного токена при создании:

class Captable < ApplicationRecord
  # ...
  after_validation :set_access_token!, if: :new_record?

  private


  def set_access_token!
    self.access_token = loop do
      random_token = SecureRandom.hex(10)
      break random_token unless self.class.exists?(access_token: random_token)
    end
  end
end

Затем вы можете использовать токен для условного пропуска обратных вызовов:

class CaptablesController
  skip_before_action :authenticate_user, if: :has_valid_access_token?, only: :show

  private
    def has_valid_access_token?
      params[:access_token].present? && Captable.exists?(params.permit(:access_token, :id))
    end
end

Это более безопасно, чем обрабатывать его в ApplicationController, поскольку вы выборочно добавляете одно исключение.

Это более простой подход, который использует один токен, чтобы дать кому-либо доступ к одному ресурсу. Вы также можете создать одноразовые токены, создав отдельную таблицу и уничтожив / аннулировав их после использования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...