J'ai ajouté une fonction de mot de passe à l'article, j'ai donc écrit un article pour cette sortie.
Vous pouvez définir le mot de passe comme indiqué dans l'image ci-dessous.
Créez une fonction de publication rapide. Si vous utilisez un échafaudage, vous pouvez le fabriquer en 1 minute.
$ rails new post_with_password
$ cd post_with_password
$ rails g scaffold Post description:text
$ rails db:migrate
Le déroulement de la publication de l'utilisateur avec un mot de passe au saut en détail
Utilisez bcrypt (gem) pour définir le mot de passe comme préparation préliminaire.
Le gem suivant est commenté dans le Gemfile, supprimez donc #. gem 'bcrypt', '~> 3.1.7'
$ bundle install
Ajoutez ensuite une phrase au modèle.
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
Ajout de has_secure_password au modèle, En ajoutant la colonne password_digest Deux attributs seront disponibles: password et password_confirmation.
Définissons le mot de passe pour le sujet principal.
Tout d'abord, laissez l'utilisateur définir un mot de passe dans la vue.
post.rb
(réduction)
<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 %>
Ajoutez ensuite: mot de passe au paramètre strong.
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
Vous pouvez maintenant enregistrer votre mot de passe dans db.
La prochaine fois que vous accédez à la page de détails, demandez un mot de passe, et s'il correspond au mot de passe que vous avez défini, redirigez vers la page de détails.
Créez une page pour authentifier votre mot de passe.
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 "Envoyer", class: 'btn-block' %>
<% end %>
</div>
</div>
</div>
</div>
Ajoutez également le routage.
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
Enfin, créez la fonction d'authentification.
posts_controller.rb
(réduction)
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
Si le message et le mot de passe correspondent, vous serez maintenant redirigé vers la page de détails.
C'est tout pour hier.
Cependant, dans ce cas, il est nécessaire de définir un mot de passe pour toutes les publications, la définition du mot de passe est donc facultative.
Puisque le has_secure_password défini par bcrypt sera retourné pour les messages vides, Ajoutez ce qui suit pour pouvoir publier même s'il est vide.
post.rb
class Post < ApplicationRecord
has_secure_password(validations: false)
end
Lorsque passwaord_digest contient un mot de passe et quand il ne le fait pas Modifiez la destination du lien de la page de détails.
ruby:index.hetml.erb
(réduction)
<% @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 %>
Cependant, avec cela, même si vous définissez un mot de passe, vous pouvez voir la description à partir de l'index.
Modifiez l'affichage de Description en fonction de la présence ou de l'absence de 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 %>
Si password_digest est vide, il sera affiché comme d'habitude, et s'il n'est pas vide, il sera affiché comme "secret".
Enfin, l'accès est restreint et il est terminé.
Si vous n'avez pas de mot de passe lorsque vous cliquez sur afficher, configurez-le pour accéder à la page de détails et si vous avez un mot de passe, vous serez redirigé vers le formulaire de saisie du mot de passe.
Cela résout également le problème que le mot de passe peut être brisé en entrant directement l'url.
Le mécanisme est le suivant.
Vérifiez s'il existe un mot de passe pour les messages / show /: id
S'il n'y a pas de mot de passe, posts / show /: id sera affiché tel quel
S'il y a un mot de passe, redirigez vers posts / show /: id si l'url contient la valeur de password_digest Si non inclus, redirigez vers le formulaire de saisie du mot de passe
L'explication doit être expliquée. Si vous n'avez pas de mot de passe, vous pouvez taper directement l'url pour afficher la page de détails, et il n'y a pas de problème. Le problème est que si vous tapez directement l'url dans un message avec un mot de passe, la page de détails sera affichée.
Pour le moment, "Redirigeons les publications avec des mots de passe vers le formulaire de saisie de mot de passe avec restrictions d'accès" Je suis accro à la pensée en court-circuit. (J'en étais accro)
Vous ne pourrez pas ouvrir la page de détails pour le reste de votre vie en utilisant la méthode ci-dessus. En effet, la page de détails a un mot de passe, que vous vous authentifiiez ou non à l'aide du formulaire de saisie de mot de passe.
Mon idée était d'envoyer les paramètres à redirect_to lorsque le mot de passe a été authentifié avec succès. Si l'url contient ce paramètre, c'est un moyen d'afficher la page de détails.
Vous pouvez également envoyer des paramètres à redirect_to. Cette fois, j'enverrai password_digest.
Il y a deux raisons.
J'ai pensé à envoyer des caractères alphanumériques aléatoires dans les paramètres à chaque fois, mais j'ai abandonné car c'était gênant de les supprimer.
En outre, il est hautement sécurisé si password_digest est inclus dans l'url, mais il peut être percé. Les valeurs sont de 60 chiffres en haut et en bas, des nombres et des symboles, donc cela peut être assez difficile.
Je suis désolé de l'expliquer pendant longtemps, mais j'écrirai le code du prochain.
Tout d'abord, définissez le paramètre sur redirect_to.
posts_controller.rb
def authenticate
post_id = Post.find(params[:id])
if post_id && post_id.authenticate(params[:post][:password])
ici-> redirect_to post_path(post_id, parameter: post_id.password_digest)
else
render 'index'
end
end
Après l'authentification par mot de passe, des paramètres seront ajoutés et l'URL changera.
Ensuite, l'accès est limité par la présence ou l'absence d'un mot de passe.
posts_controller.rb
before_action :with_password, only: :show
(réduction)
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: 's'il vous plait entrez votre mot de passe'
end
end
Je vais expliquer dans l'ordre du haut. url = request.url Obtenez d'abord l'URL avec le code ci-dessus.
Je suis devenu accro ici quand j'écrivais le code. Même si j'ai obtenu l'URL telle quelle, elle n'a pas été authentifiée.
Lorsque vous comparez le contenu de url et password_digest à l'aide de byebug, certains caractères tels que $ sont C'était différent. Quand je l'ai recherché, il semblait y avoir des chaînes qui ne pouvaient pas être utilisées dans l'url, donc j'ai dû les encoder.
Je n'ai pas trouvé de moyen de le convertir en une seule fois, alors je l'ai changé de force en utilisant gsub. (S'il existe une autre bonne façon de l'écrire, merci de me le faire savoir.)
J'ai évoqué les informations suivantes. https://www.seil.jp/doc/index.html#tool/url-encode.html
Ceci termine l'acquisition de l'url.
Ceci est la finition finale. Le code suivant est expliqué et il est terminé.
if [email protected]_digest.nil? && !url.try(:include?, @post.password_digest)
Si vous essayez d'ouvrir la page de détails avec un mot de passe et que l'URL ne contient pas password_digest Redirigez vers le formulaire de saisie du mot de passe.
Si vous n'utilisez pas try, une erreur se produira si vous n'avez pas de mot de passe.
C'est tout.
Veuillez utiliser bcrypt autre que la connexion.
J'espère que cela sera utile pour votre portfolio.
Recommended Posts