Ich habe dem Beitrag eine Passwortfunktion hinzugefügt und einen Artikel für diese Ausgabe geschrieben.
Sie können das Passwort wie in der Abbildung unten gezeigt einstellen.
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
Der Ablauf vom Benutzerbeitrag mit einem Passwort bis zum Detailspringen
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.
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.
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
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.
Ä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.
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.
Überprüfen Sie, ob ein Passwort für posts / show /: id vorhanden ist
Wenn kein Passwort vorhanden ist, werden die Beiträge / show /: id unverändert angezeigt
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
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.
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.
Das ist es.
Bitte verwenden Sie bcrypt außer login.
Ich hoffe, es wird für Ihr Portfolio hilfreich sein.
Recommended Posts