- 投稿日:2020-09-17T22:31:24+09:00
[laravel] 非同期でサクッと作るいいね機能
いいね機能自体、様式は違えど多くのサイトで見る機能ですね~
今回はAjaxを使って非同期を行っていますが、流れはこんな感じです
冒頭で紹介したサンプルをこちらにあり、Seederをつくっているので簡単に確認できるかと思います
コーディング
index.blade.php : 実際に表示する画面
like.js :いいねボタンが押されたときの処理と、実際にHTMLを書き換える処理
ProductController : jsから送られてきたデータを処理するメソッドを持つコントローラー
※authが有効になっているが前提index.blade.php@if(auth()->user()) @if(isset($product->like_products[0])) <a class="toggle_wish" product_id="{{ $product->id }}" like_product="1"> <i class="fas fa-heart"></i> </a> @else <a class="toggle_wish" product_id="{{ $product->id }}" like_product="0"> <i class="far fa-heart"></i> </a> @endif @endiflike.js$(function () { //「toggle_wish」というクラスを持つタグがクリックされたときに以下の処理が走る $('.toggle_wish').on('click', function () { //表示しているプロダクトのIDと状態、押下し他ボタンの情報を取得 product_id = $(this).attr("product_id"); like_product = $(this).attr("like_product"); click_button = $(this); $.ajax({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') //基本的にはデフォルトでOK }, url: '/like_product', //route.phpで指定したコントローラーのメソッドURLを指定 type: 'POST', //GETかPOSTメソットを選択 data: { 'product_id': product_id, 'like_product': like_product, }, //コントローラーに送るに名称をつけてデータを指定 }) //正常にコントローラーの処理が完了した場合 .done(function (data) //コントローラーからのリターンされた値をdataとして指定 { if ( data == 0 ) { //クリックしたタグのステータスを変更 click_button.attr("like_product", "1"); //クリックしたタグの子の要素を変更(表示されているハートの模様を書き換える) click_button.children().attr("class", "fas fa-heart"); } if ( data == 1 ) { //クリックしたタグのステータスを変更 click_button.attr("like_product", "0"); //クリックしたタグの子の要素を変更(表示されているハートの模様を書き換える) click_button.children().attr("class", "far fa-heart"); } }) ////正常に処理が完了しなかった場合 .fail(function (data) { alert('いいね処理失敗'); alert(JSON.stringify(data)); }); }); });ProductControllerpublic function like_product(Request $request) { if ( $request->input('like_product') == 0) { //ステータスが0のときはデータベースに情報を保存 LikeProduct::create([ 'product_id' => $request->input('product_id'), 'user_id' => auth()->user()->id, ]); //ステータスが1のときはデータベースに情報を削除 } elseif ( $request->input('like_product') == 1 ) { LikeProduct::where('product_id', "=", $request->input('product_id')) ->where('user_id', "=", auth()->user()->id) ->delete(); } return $request->input('like_product'); }あとがき
まだまだ修行中の身なので、記事の書き方やコードについてアドバイスや編集リクエスト等があれば教えてください!
- 投稿日:2020-09-17T17:56:51+09:00
Laravelでログインユーザーメールアドレスを暗号化して保存する
Laravelのユーザー登録に関してですが、
パスワードはハッシュ化して保存されますが、メールアドレスはプレーンテキストで保存されるため、
セキュリティ強化で暗号化して保存させます。まずはユーザーモデルのメールアドレスを取り出すときに自動で暗号化/復号化されるように設定します。
app/Models/User.phppublic function getEmailAttribute($value) { return openssl_decrypt($value, 'AES-128-ECB', '暗号化キー'); } public function setEmailAttribute($value) { $this->attributes['email'] = openssl_encrypt($value, 'AES-128-ECB', '暗号化キー')); }次にログイン時のメールアドレスのチェックに関してですが、そのままだと暗号化前のメールアドレスと、暗号化された文字列でログインチェックがなされるのでログインできません。
そこで、ログインチェックの前にメールアドレスを暗号化してあげます。app/Http/Controllers/Auth/LoginController.phpprotected function credentials(Request $request) { $request->merge(['email' => openssl_encrypt($request->input('email'), 'AES-128-ECB', '暗号化キー')]); return $request->only($this->username(), 'password'); }これでログインまでできるはずです。
デフォルトのままだと、ログイン失敗した後、暗号化されたメールアドレスが表示されてしまいますので適当に修正してください。暗号化で毎回同じ文字列が作成されるためセキュリティ的にはそんなに大丈夫なわけではありませんが、平文で保存するよりはましかと思います。
また暗号化のアルゴリズムに関してですが、可逆式で毎回同じ結果で暗号化する必要があります。
Crypt::encryptStringは毎回異なる結果になるのでログイン時の処理にもうひと手間かける必要があります。おわり。
- 投稿日:2020-09-17T12:05:37+09:00
Laravel ToDoアプリチュートリアルで発生した エラーUnexpected data found. Data missing
初めに
仕事でLaravelの知識が必要となり、下記リンクの良さげなチュートリアルをやっていまた。
https://www.hypertextcandy.com/laravel-tutorial-create-taskチュートリアル通りにやっていてもエラーってやっぱり起きるのですよね〜。。。
環境
上記リンクのチュートリアルはv5らしいです。私はv6だったので発生したエラーだと思われる。。。
$ php artisan --version Laravel Framework 6.18.40同じようなエラーです。。
Laravel getFormattedDueDateAttributeでTrailing data のエラーが出た場合発生した問題
上記リンクのチュートリアル通りにやっても、「タスクを保存する」の段階でこのようなエラーが発生しました。
Carbon\Exceptions\InvalidFormatException Unexpected data found. Unexpected data found. Data missing (View: /Users/xxx/resources/views/tasks/index.blade.php)
解決方法
https://qiita.com/koukonko/items/420a95e6e98915b8a38b
上記を参考にTaskController.php
を編集したところ、正常に保存されて表示できました。TaskController.php//変更前 $task->due_date = $request->due_date; //変更後 $task->due_date = $request->due_date = date('Y-m-d H:i:s');TaskController.php/** * GET /folders/{id}/tasks/create */ public function showCreateForm(int $id) { return view('tasks/create', [ 'folder_id' => $id ]); } public function create(int $id, CreateTask $request) { $current_folder = Folder::find($id); $task = new Task(); $task->title = $request->title; // date('Y-m-d H:i:s')を追加! $task->due_date = $request->due_date = date('Y-m-d H:i:s'); $current_folder->tasks()->save($task); return redirect()->route('tasks.index', [ 'id' => $current_folder->id, ]);