[RUBY] [Rails] Wie man ein Passwort für Beiträge festlegt, wurden URL-Direkttreffer-Maßnahmen ergriffen

So legen Sie ein Passwort für einen Beitrag fest

Ich habe dem Beitrag eine Passwortfunktion hinzugefügt und einen Artikel für diese Ausgabe geschrieben.

Ziel dieses Artikels

Sie können das Passwort wie in der Abbildung unten gezeigt einstellen.

post_with_password.gif

Erstellen Sie eine Buchungsfunktion

Erstellen Sie eine Schnellbuchungsfunktion. Wenn Sie ein Gerüst verwenden, können Sie es in 1 Minute machen.

$ rails new post_with_password $ cd post_with_password $ rails g scaffold Post description:text $ rails db:migrate

投稿機能.gif

Stellen Sie bcrypt ein

Der Ablauf vom Benutzerbeitrag mit einem Passwort bis zum Detailspringen

  1. Legen Sie beim Posten ein Passwort fest (posts / new)
  2. Fordern Sie beim Öffnen der Detailseite ein Passwort an (posts / show /: id) (falls ein Passwort vorhanden ist)
  3. Wenn ID und Passwort übereinstimmen, leiten Sie zur Detailseite weiter

Verwenden Sie bcrypt (gem), um das Passwort als vorbereitende Vorbereitung festzulegen.

Das folgende Juwel ist in der Gem-Datei auskommentiert, löschen Sie also #. gem 'bcrypt', '~> 3.1.7'

$ bundle install

Fügen Sie dann dem Modell einen Satz hinzu.

ruby:_form.html.erb


class Post < ApplicationRecord
  has_secure_password
end

$ rails g migration add_password_digest_to_posts password_digest:string $ rails db:migrate

Has_secure_password zum Modell hinzugefügt, Durch Hinzufügen der Spalte password_digest Es stehen zwei Attribute zur Verfügung: password und password_confirmation.

1. Legen Sie beim Posten ein Passwort fest

Lassen Sie uns das Passwort für das Hauptthema festlegen.

Lassen Sie den Benutzer zunächst ein Kennwort in der Ansicht festlegen.

post.rb


(Kürzung)
  <div class="field">
    <%= form.label :description %>
    <%= form.text_area :description %>
  </div>
  
  <div class="field">
    <%= form.label :password %>
    <%= form.password_field :password %>
  </div>

  <div class="actions">
    <%= form.submit %>
  </div>
<% end %>

Fügen Sie dann dem starken Parameter: password hinzu.

posts_controller.rb


  private
    # Use callbacks to share common setup or constraints between actions.
    def set_post
      @post = Post.find(params[:id])
    end

    # Only allow a list of trusted parameters through.
    def post_params
      params.require(:post).permit(:description, :password)
    end
end

Sie können jetzt Ihr Passwort in db speichern.

2. Fordern Sie ein Passwort an, um die Detailseite zu öffnen

Wenn Sie das nächste Mal zur Detailseite gehen, fragen Sie nach einem Passwort. Wenn es mit dem von Ihnen festgelegten Passwort übereinstimmt, leiten Sie zur Detailseite weiter.

Erstellen Sie eine Seite zur Authentifizierung Ihres Passworts.

ruby:posts_with_password.html.erb


<div class="users-new-wrapper">
  <div class="container">
    <div class="row">
      <div class="col-md-offset-4 col-md-4 users-new-container">
        <h1 class="text-center text-white">password</h1>
        <%= form_for(:post, {controller: 'posts', action: "posts_with_password/#{@post}" }) do |f| %>
          <div class="form-group">
            <%= f.label :password %>
            <%= f.password_field :password, class: 'form-control' %>
          </div>
            <%= f.submit "Senden", class: 'btn-block' %>
        <% end %>
      </div>
    </div>
  </div>
</div>

Fügen Sie auch Routing hinzu.

qiita.rb


Rails.application.routes.draw do
  resources :posts
  get       'posts_with_password/:id', to: 'posts#posts_with_password'
  post      'posts_with_password/:id', to: 'posts#authenticate'
end

Zur Detailseite umleiten, wenn das Passwort übereinstimmt

Erstellen Sie abschließend die Authentifizierungsfunktion.

posts_controller.rb


(Kürzung)
 def authenticate
    post_id = Post.find(params[:id])
    if post_id && post_id.authenticate(params[:post][:password])
      redirect_to post_path(post_id)
    else
      render 'posts_with_password'
    end
  end

  def posts_with_pass

Wenn der Beitrag und das Passwort übereinstimmen, werden Sie jetzt zur Detailseite weitergeleitet.

Das war's für gestern.

In diesem Fall muss jedoch für alle Beiträge ein Kennwort festgelegt werden, sodass das Festlegen des Kennworts optional ist.

Da das von bcrypt festgelegte has_secure_password für leere Beiträge umgedreht wird, Fügen Sie Folgendes hinzu, damit Sie auch dann posten können, wenn es leer ist.

post.rb


class Post < ApplicationRecord
  has_secure_password(validations: false)
end

Wenn passwaord_digest ein Passwort enthält und wenn nicht Ändern Sie das Linkziel der Detailseite.

ruby:index.hetml.erb


(Kürzung)
<% @posts.each do |post| %>
  <tr>
    <td><%= post.description %></td>
    <td><%= link_to 'Show', post_path(post) %></td>
    <td><%= link_to 'Edit', edit_post_path(post) %></td>
    <td><%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %></td>
  </tr>
<% end %>

Selbst wenn Sie ein Kennwort festlegen, können Sie damit die Beschreibung aus dem Index anzeigen.

スクリーンショット 2020-07-13 14.02.37.jpeg

Ändern Sie die Anzeige von Beschreibung abhängig vom Vorhandensein oder Fehlen von password_digest.

ruby:index.hetml.erb


<% @posts.each do |post| %>
  <tr>
    <% if post.password_digest.nil? %>
      <td><%= post.description %></td>
    <% else %>
      <td>secret</td>
    <% end %>
    <td><%= link_to 'Show', post_path(post) %></td>
    <td><%= link_to 'Edit', edit_post_path(post) %></td>
    <td><%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %></td>
  </tr>
<% end %>

Wenn password_digest leer ist, wird es wie gewohnt angezeigt, und wenn es nicht leer ist, wird es als "geheim" angezeigt.

Zugriff einschränken

Schließlich ist der Zugriff eingeschränkt und abgeschlossen.

Wenn Sie beim Klicken auf Anzeigen kein Kennwort haben, stellen Sie es so ein, dass zur Detailseite gesprungen wird. Wenn Sie ein Kennwort haben, werden Sie zum Kennworteingabeformular weitergeleitet.

Es löst auch das Problem, dass das Passwort durch direkte Eingabe der URL gebrochen werden kann.

Der Mechanismus ist wie folgt.

  1. Überprüfen Sie, ob ein Passwort für posts / show /: id vorhanden ist

  2. Wenn kein Passwort vorhanden ist, werden die Beiträge / show /: id unverändert angezeigt

  3. Wenn ein Kennwort vorhanden ist, leiten Sie zu posts / show /: id um, wenn die URL den Wert password_digest enthält Wenn nicht enthalten, leiten Sie zum Passworteingabeformular weiter

  4. Die Erklärung muss erklärt werden. Wenn Sie kein Passwort haben, können Sie die URL direkt eingeben, um die Detailseite anzuzeigen, und es gibt kein Problem. Das Problem ist, dass die Detailseite angezeigt wird, wenn Sie die URL direkt in einen Beitrag mit einem Kennwort eingeben.

Vorerst "Leiten wir Posts mit Passwörtern mit Zugriffsbeschränkungen auf das Passworteingabeformular um". Ich bin süchtig danach, kurzgeschlossen zu denken. (Ich war süchtig danach)

Mit der oben beschriebenen Methode können Sie die Detailseite für den Rest Ihres Lebens nicht öffnen. Dies liegt daran, dass die Detailseite ein Kennwort enthält, unabhängig davon, ob Sie sich mithilfe des Kennworteingabeformulars authentifizieren.

Meine Idee war, die Parameter an redirect_to zu senden, wenn das Passwort erfolgreich authentifiziert wurde. Wenn die URL diesen Parameter enthält, können Sie auf dieser Seite die Detailseite anzeigen.

Sie können auch Parameter an redirect_to senden. Dieses Mal werde ich password_digest senden.

Es gibt zwei Gründe.

  1. Weil es leicht herauszunehmen ist
  2. Weil es sehr sicher ist

Ich habe darüber nachgedacht, jedes Mal zufällige alphanumerische Zeichen in den Parametern zu senden, aber ich habe aufgegeben, weil es schwierig war, sie herauszunehmen.

Es ist auch sehr sicher, wenn password_digest in der URL enthalten ist, aber es kann durchbrochen werden. Die Werte sind 60-stellig oben und unten, Zahlen und Symbole, daher kann es ziemlich schwierig sein.

Es tut mir leid, das lange zu erklären, aber ich werde den Code ab dem nächsten schreiben.

Setzen Sie zuerst den Parameter auf redirect_to.

posts_controller.rb


def authenticate
    post_id = Post.find(params[:id])
    if post_id && post_id.authenticate(params[:post][:password])
Hier-> redirect_to post_path(post_id, parameter: post_id.password_digest)
    else
      render 'index'
    end
  end

Nach der Passwortauthentifizierung werden Parameter hinzugefügt und die URL geändert.

Als nächstes wird der Zugriff durch das Vorhandensein oder Fehlen eines Passworts eingeschränkt.

posts_controller.rb


before_action :with_password, only: :show

(Kürzung)
private
  def with_password
    url = request.url.gsub!(/%21|%22|%23|%24|%24|%25|%26|%27|%28|%29|%2A|%2B|%2C|%2F|%3A|%3B|%3C|%3D|%3E|%3F|%40|%5B|%5D|%5E|%60|%7B|%7C|%7D|%7E|/,
    "%21" => "!", "%22" => '"', "%23" => "#", "%24" => "$", "%25" => "%", "%26" => "&", "%27" => "'", "%28" => "(", "%29" => ")",
    "%2A" => "*", "%2B" => "+", "%2C" => ",", "%2F" => "/", "%3A" => ":", "%3B" => ";", "%3C" => "<", "%3D" => "=", "%3E" => ">", "%3F" => "?", "%40" => "@",
    "%5B" => "[", "%5D" => "]", "%5E" => "^", "%60" => "`", "%7B" => "{", "%7C" => "|", "%7D" => "}", "%7E" => "~")
    @post = Post.find(params[:id])
    if [email protected]_digest.nil? && !url.try(:include?, @post.password_digest)
      redirect_to "/posts_with_password/#{@post.id}", danger: 'Bitte geben Sie Ihr Passwort ein'
    end
  end

Ich werde in der Reihenfolge von oben erklären. url = request.url Holen Sie sich zuerst die URL mit dem obigen Code.

Ich war hier süchtig, als ich den Code schrieb. Selbst wenn ich die URL so wie sie war erhalten habe, wurde sie nicht authentifiziert.

Beim Vergleichen des Inhalts von url und password_digest mit byebug werden einige Zeichen wie $ verwendet Es war anders. Als ich es nachgeschlagen habe, schien es einige Zeichenfolgen zu geben, die nicht in der URL verwendet werden konnten, also musste ich sie codieren.

Ich konnte keinen Weg finden, es auf einmal zu konvertieren, also habe ich es mit gsub zwangsweise geändert. (Wenn es eine andere gute Möglichkeit gibt, es zu schreiben, lassen Sie es mich bitte wissen.)

Ich bezog mich auf die folgenden Informationen. https://www.seil.jp/doc/index.html#tool/url-encode.html

Damit ist die Erfassung der URL abgeschlossen.

Dies ist das endgültige Ziel. Der folgende Code wird erklärt und ist abgeschlossen.

if [email protected]_digest.nil? && !url.try(:include?, @post.password_digest)

Wenn Sie versuchen, die Detailseite mit einem Passwort zu öffnen und die URL kein password_digest enthält Weiterleiten zum Passworteingabeformular.

Wenn Sie try nicht verwenden, tritt ein Fehler auf, wenn Sie kein Kennwort haben.

Zusammenfassung

Das ist es.

Bitte verwenden Sie bcrypt außer login.

Ich hoffe, es wird für Ihr Portfolio hilfreich sein.

Recommended Posts

[Rails] Wie man ein Passwort für Beiträge festlegt, wurden URL-Direkttreffer-Maßnahmen ergriffen
[Rails 6] So legen Sie ein Hintergrundbild in Rails [CSS] fest
Maßnahmen zum langen Laden von Bildern (Rails)
[Docker] So erstellen Sie eine virtuelle Umgebung für Rails- und Nuxt.js-Apps
So fügen Sie ein Video in Rails ein
So erstellen Sie ein Maven-Repository für 2020
[Rails] So erstellen Sie eine Teilvorlage
Benötigt für iOS 14? So legen Sie NSUserTrackingUsageDescription fest
Schienen: Wie man eine Rechenaufgabe schön schreibt
So erstellen Sie überall eine H2-Datenbank
Mit Rails in eine Tag-zu-URL-Zeichenfolge konvertieren
[Rails] Wie schreibe ich, wenn ich eine Unterabfrage mache?
[Rails] So erstellen Sie ein Diagramm mit lazy_high_charts
So erstellen Sie Pagenationen für das "Kaminari" -Array
[Rails] So implementieren Sie einen Unit-Test eines Modells
So erstellen Sie eine leichte JRE für den Vertrieb
[Java] (für MacOS) Methode zur Einstellung des Klassenpfads
So implementieren Sie eine ähnliche Funktion in Rails
So erstellen Sie einfach ein Pulldown mit Rails
[Rails] So erstellen Sie eine Twitter-Freigabeschaltfläche
[Ruby on Rails] So implementieren Sie die Tagging- / inkrementelle Suchfunktion für Posts (ohne Gem)