
[Laravel] 5.6.14がリリースされました
laravel/frameworkのバージョン5.6.14がリリースされました。更新された機能について確認していきます。
Added
1. SlackMessage::info()メソッドが追加されました (#23711)
Slack通知のレベルはデフォルトでinfoでしたが、これを明示的に指定できるようになりました。
2. SessionGuard::logoutOtherDevices()メソッドが追加されました (@9c51e49)
使用しているデバイス以外のユーザーセッション情報を無効にすることができます。この機能を利用するためには\Illuminate\Session\Middleware\AuthenticateSessionミドルウェアを利用している必要があります。
use Illuminate\Support\Facades\Auth;
Auth::logoutOtherDevices($password);
詳しい変更については以下を確認してください。
Release v5.6.14 · laravel/framework · GitHub

[Laravel] 5.6.13がリリースされました
laravel/frameworkのバージョン5.6.13がリリースされました。更新された機能について確認していきます。
Added
1. view:cacheコマンドが追加されました (@9fd1273, @2ab8acf)
2. コレクションのmin()、max()メソッドがショートコードによるアクセスが可能になりました (#23560)
以下のようにエイリアスとして利用できます。
$c->min('foo');
$c->max('foo');
// ショートコード
$c->min->foo;
$c->max->foo;
3. Bladeディレクテイブに@elseauth、@elseguestが追加されました (#23569)
認証方法によって分岐ができるようになりました。
@auth('administrator')
@elseauth('standard')
@endauth
4. 暗号化のレベルを設定できるようになりました (#23573, @d6e3ca9)
以下のようにconfig/hashing.phpにてカスタマイズが可能になりました。
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Hash Driver
|--------------------------------------------------------------------------
|
| This option controls the default hash driver that will be used to hash
| passwords for your application. By default, the bcrypt algorithm is
| used; however, you remain free to modify this option if you wish.
|
| Supported: "bcrypt", "argon"
|
*/
'driver' => 'bcrypt',
/*
|--------------------------------------------------------------------------
| Bcrypt Options
|--------------------------------------------------------------------------
|
| Here you may specify the configuration options that should be used when
| passwords are hashed using the Bcrypt algorithm. This will allow you
| to control the amount of time it takes to hash the given password.
|
*/
'bcrypt' => [
'rounds' => 10,
],
/*
|--------------------------------------------------------------------------
| Argon Options
|--------------------------------------------------------------------------
|
| Here you may specify the configuration options that should be used when
| passwords are hashed using the Argon algorithm. These will allow you
| to control the amount of time it takes to hash the given password.
|
*/
'argon' => [
'memory' => 1024,
'threads' => 2,
'time' => 2,
],
];
5. タグ付けされたキャッシュキーのincrementとdecrementが可能になりました (#23578)
6. SeeInOrderのテストが追加されました (#23594, @ca39449)
7. コレクションのgroupBy()メソッドがショートコードによるアクセスが可能になりました (#23608)
8. created_atの更新を無効化出来るようになりました (#23667)
CREATED_AT、UPDATED_AT共にnullを指定することで日付の挿入をスキップ可能になりました。
class Model extends Eloquent
{
public const CREATED_AT = null;
public const UPDATED_AT = null;
}
9. optional()ヘルパーにコールバックが渡せるようになりました (#23688)
10. Eloquent\Collection::loadMorph()メソッドが追加されました (#23626)
morphリレーションのレコードについてもEager Loadingが可能になりました。
$activities = ActivityFeed::with('parentable')
->get()
->loadMorph('parentable', [
Event::class => 'calendar',
Photo::class => 'tags',
Post::class => ['author', 'commentsCount'],
]);
詳しい変更については以下を確認してください。
Release v5.6.13 · laravel/framework · GitHub

[Laravel] EloquentモデルでJSON型のカラムを扱う方法
MySQL 5.7ではカラム型にJSONを扱えるようになりました。もちろんLaravelのEloquentも対応しており、簡単に読み取りや検索を行うことができます。
実践的なアプリケーションでMySQLのJSON型を扱う方法について検証してみましょう。
テーブルの作成
JSON型を扱うテーブルのModelと、migrationファイルを作成します。
$ php artisan make:model Archive -m
今回はarchivesというテーブルにユーザー情報を持つmetaカラムがあるとします。
// database/migrations/2018_03_28_013327_create_archives_table.php
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateArchivesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('archives', function (Blueprint $table) {
$table->increments('id');
$table->json('meta');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('archives');
}
}
JSON型に対応していないバージョンの場合はTEXT型で作成しましょう。
Eloquentモデルのcastsプロパティに値を指定することで、データベースから取得した値を指定したフォーマットへ変更することができるようになります。
int (integer)
real (float, double)
string
bool (boolean)
object
array (json)
collection
date
datetime (custom_datetime)
timestamp
metaカラムをJSONへキャストするように設定しておきましょう。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Archive extends Model
{
protected $guarded = ['*'];
protected $casts = ['meta' => 'json'];
}
Factory (ダミーデータ) の作成
データの登録を簡単にするために、Archiveに対してのFactoryを作成しておきましょう。
$ php artisan make:factory ArchiveFactory
metaカラムに対して、名前、フリガナ、住所、メールアドレスが登録されるものとします。
Fakerを利用してダミーデータを登録できるようにします。
※ config/app.phpに'faker_locale' => 'ja_JP'を追加することで日本語に対応したダミーデータの作成が可能になります。
<?php
use Faker\Generator as Faker;
/** @var \Illuminate\Database\Eloquent\Factory $factory */
$factory->define(App\Archive::class, function (Faker $faker) {
return [
'meta' => [
'name' => $faker->name,
'kana' => $faker->kanaName,
'address' => $faker->address,
'email' => $faker->email
]
];
});
Factoryが作成できたらtinkerを使ってダミーデータを登録しておきましょう。
$ php artisan tinker
Psy Shell v0.8.17 (PHP 7.1.10 — cli) by Justin Hileman
>>> factory(App\Archive::class, 100)->create();
コントローラー&Viewファイルの作成
登録されたArchive情報を取得するためのコントローラーを作成します。
$ php artisan make:controller ArchiveController
対応するルーティングも追加しておきましょう。
// routes/web.php
Route::get('archive', 'ArchiveController');
Archive情報の一覧表示に加えて、metaカラムのJSON情報を検索できるようにしてみましょう。
以下のようなクエリを発行することで、JSON型のカラムに対しての条件検索ができます。
select * from `archives` where `meta`->'$."name"' like '%鈴木%'
これをEloquentのORMで利用するには以下のように記述します。
Archive::where('meta->name', 'like', '%鈴木%');
Illuminate\Database\Query\Grammars\MySqlGrammar::wrapJsonSelectorにより、->に対してラップ処理が行われ、%s->'$.%s'に置換されてJSON型の検索が可能になります。
/**
* Wrap the given JSON selector.
*
* @param string $value
* @return string
*/
protected function wrapJsonSelector($value)
{
$path = explode('->', $value);
$field = $this->wrapValue(array_shift($path));
return sprintf('%s->\'$.%s\'', $field, collect($path)->map(function ($part) {
return '"'.$part.'"';
})->implode('.'));
}
Archiveテーブルの検索条件に使うパラメーターが?q=name:田中,address=東京都の用に送られてくるとして、ここから必要な条件のトリミングを行いkey:valueをもつコレクションを作成します。
以上をふまえて以下のようなコントローラーを作成します。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use App\Archive;
class ArchiveController extends Controller
{
protected $metaKeys = ['name', 'kana', 'address', 'email'];
public function __invoke(Request $request)
{
$searchMetas = array_reduce(explode(',', $request->q), function($meta, $q) {
$key = str_before($q, ':');
$value = str_after($q, ':');
if (in_array($key, $this->metaKeys) && filled($value)) {
$meta->put($key, $value);
}
return $meta;
}, new Collection);
$model = Archive::query();
foreach ($this->metaKeys as $metaKey) {
if ($searchMetas->has($metaKey)) {
$model->where('meta->'.$metaKey, 'like', '%'.$searchMetas->get($metaKey).'%');
}
}
$archives = $model->get();
return view('archive', compact('archives', 'searchMetas'));
}
}
resources/viewsへarchive.blade.phpを作成します。
Laravelに同封されているBootstrapを利用して以下の用に作成します。
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<title>{{ config('app.name') }}</title>
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
<meta name="csrf-token" content="{{ csrf_token() }}">
</head>
<body>
<div class="container my-5">
<form class="form-row" action="{{ URL::current() }}">
<div class="col">
<div class="form-group mx-sm-3">
<input type="text" class="form-control" name="q" value="{{ Request::get('q') }}" placeholder="key1:value1,key2:value2...">
</div>
</div>
<div class="col">
<button type="submit" class="btn btn-primary">Search</button>
</div>
</form>
</div>
<div class="container my-5">
<div class="list-group">
@foreach ($archives as $archive)
<a href="#" class="list-group-item list-group-item-action flex-column align-items-start">
<div class="mt-2">
<dl class="row">
<dt class="col-sm-2">名前</dt>
<dd class="col-sm-10 meta-name">{{ $archive->meta['name'] }}</dd>
<dt class="col-sm-2">フリガナ</dt>
<dd class="col-sm-10 meta-kana">{{ $archive->meta['kana'] }}</dd>
<dt class="col-sm-2">住所</dt>
<dd class="col-sm-10 meta-address">{{ $archive->meta['address'] }}</dd>
<dt class="col-sm-2">メールアドレス</dt>
<dd class="col-sm-10 meta-email">{{ $archive->meta['email'] }}</dd>
</dl>
</div>
</a>
@endforeach
</div>
</div>
<script src="{{ asset('js/app.js') }}"></script>
</body>
</html>
/archiveへアクセスすると一覧が表示されます。
検索フォームにname:田と入力して検索していみます。
meta情報のnameに田が入っている情報が出力されました。
(番外編) 検索にヒットした文字列をハイライトする
Laravelとは関係ありませんが、検索した文字列をハイライトさせることで、より視覚的に判断することができます。
Javascriptのmark.jsを利用してマーキングを行います。
js/app.jsを読み込んでいる下に以下のコードを追加します。
<script src="{{ asset('js/app.js') }}"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.11.1/jquery.mark.min.js"></script>
<script>
@foreach ($searchMetas as $key => $value)
$(".meta-{{ $key }}").mark('{{ $value }}');
@endforeach
</script>
検索したキーワードがハイライトされます。

[Laravel] ユーザーのアクセスログを保存する
アプリケーションへアクセスしたユーザーのアクセスログは何かと役に立つので取っておきたいと思う人が多いと思います。
Laravelには認証系のイベントが用意されており、ログインしているユーザーからのリクエストがあった場合にIlluminate\Auth\Events\Authenticatedイベントが発火されます。このイベントを購読することで、アクセスログの取得が可能です。
保存先には色々考えられますが、オンラインのログサービスのRollbarへ保存する方法を紹介します。Rollbar本来の利用方法とは異なるかもしれませんが、とても利便性の高いログ情報を取得することができます。
データベース等、保存先を変更する場合でもリスナーを変更すれば同じような動作が可能です。
パッケージの導入
Composerでxzxzyzyz/laravel-logging-rollbarをインストールします。
パッケージの詳細についてはGitHub - xzxzyzyz/laravel-logging-rollbar: Rollbar for Laravel Loggingを参照してください。
$ composer require xzxzyzyz/laravel-logging-rollbar
Rollbarの準備
Rollbarのアカウントをお持ちでない場合は以下からサインアップしてください。無料プランも用意されており、5,000件/月まで利用できます。
Rollbar
create new projectで任意のプロジェクトを作成しましょう。
作成が完了するとプロジェクトへのアクセストークンが発行されます。
Laravel側で利用するのはserver-side access tokenなので、この情報を.envファイルへ追記します。
LOG_ROLLBAR_TOKEN=your post_server_item token
config/logging.phpへRollbarのchannelを追加することで、Rollbarへの
通知をLaravelのログとして利用できるようになります。
// channelsへ追加
'channels' => [
...
'rollbar' => [
'driver' => 'custom',
'access_token' => env('LOG_ROLLBAR_TOKEN'),
'via' => Xzxzyzyz\Laravel\Logging\Rollbar\RollbarLogger::class
],
],
アクセスログを保存するリスナーの作成
以下の用なIlluminate\Auth\Events\Authenticatedイベントのリスナーを作成しましょう。
今回はログのラベルとしてアクセスのあったURLを利用します。
<?php
namespace App\Listeners;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Auth\Events\Authenticated;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\URL;
class AccessLogToRollbarListener
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* @param object $event
* @return void
*/
public function handle(Authenticated $event)
{
Log::channel('rollbar')->info(URL::current());
}
}
作成したリスナーをEventServiceProviderへ登録します。
// app/Providers/EventServiceProvider.php
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
'Illuminate\Auth\Events\Authenticated' => [
'App\Listeners\AccessLogToRollbarListener',
],
];
以上でアクセスログをRollbarへ保存する準備ができました。
次に実際にログを送信してみます。
アクセスログの確認
migrationを実行してユーザー情報の入れ物を用意しておきます。
$ php artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_000000_create_users_table
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated: 2014_10_12_100000_create_password_resets_table
認証周りを有効にしておきます。
$ php artisan make:auth
Authentication scaffolding generated successfully.
/registerへアクセスしてユーザー登録を行うのと同じですが、tinkerを利用してユーザーを作成します。
$ php artisan tinker
Psy Shell v0.8.17 (PHP 7.1.10 — cli) by Justin Hileman
>>> factory(App\User::class)->create();
=> App\User {#790
name: "Sally Stiedemann",
email: "[email protected]",
updated_at: "2018-03-23 02:21:32",
created_at: "2018-03-23 02:21:32",
id: 1,
}
>>>
/loginへアクセスして作成したユーザーでログインした後、Rollbarへアクセスしてログを確認してみましょう。
Peopleでユーザー毎のログを確認できます。
Rollbarではユーザーのリクエスト値やサーバー情報、SESSION情報、利用ブラウザ等の様々なデータが格納でき、柔軟な検索が可能です。
とても便利なサービスですので、この機会に是非使ってみましょう。

[Laravel] ログの保存先にオンラインのRoolbarを使う
Laravelのログは通常ローカルの/storage/logsディレクトリへ保存されますが、オンライン上のエラーモニタリングサービスのRollbarへ保存してみましょう。
Error Tracking & Crash Reporting for Software Developers - Rollbar
Laravelのバージョン5.6で、Log周りに関する大きなアップデートがありました。
Loggingにchannel形式が採用され、一つ、あるいは複数の場所へログを保存できるようになりました。
デフォルトで便利なドライバが複数用意されていますが、オリジナルのchannnelを作成してRollbarへログを送信します。
公式のパッケージ
Rollbarでは公式に以下のLaravel用のパッケージが用意されています。
GitHub - rollbar/rollbar-php-laravel: Rollbar error monitoring integration for Laravel projects
しかしこれは5.6に対応したロギングドライバではなく、単に今までのログシステムの拡張として、全てのログをRollbarへ送信する実装です。
src/RollbarServiceProvider.php のbootメソッドを見てみましょう。
/**
* Bootstrap the application events.
*/
public function boot()
{
// Don't boot rollbar if it is not configured.
if ($this->stop() === true) {
return;
}
$app = $this->app;
// Listen to log messages.
$app['log']->listen(function () use ($app) {
$args = func_get_args();
// Laravel 5.4 returns a MessageLogged instance only
if (count($args) == 1) {
$level = $args[0]->level;
$message = $args[0]->message;
$context = $args[0]->context;
} else {
$level = $args[0];
$message = $args[1];
$context = $args[2];
}
$app['Rollbar\Laravel\RollbarLogHandler']->log($level, $message, $context);
});
}
ログイベントのリスナーとして、Rollbarへのログ送信を登録しています。
Auto-Discoveryに対応しているので、composerでパッケージの追加を行った時点でこのリスナーが追加されることになります。5.6でも利用可能ですが、二重にログが保存されるでしょう。
カスタムドライバの実装
前述のサービスプロバイダを参考にして、Laravel5.6のログchannelとして実装します。
channelの登録には、Monolog\Loggerインスタンスを返すクラスを実装するだけです。
インスタンスの作成にはchannel名と、Monolog\Handlerが必要ですが。
公式パッケージより、Rollbar\Laravel\RollbarLogHandlerが利用できるので、これをMonolog\Handler\PsrHandlerとしてハンドラへ登録します。
// RollbarLoggerクラス
public function __invoke(array $config)
{
$defaults = [
'environment' => app()->environment(),
'root' => base_path(),
];
$config = array_merge($defaults, $config);
if (empty($config['access_token'])) {
throw new \InvalidArgumentException('Rollbar access token not configured');
}
if (empty($config['person_fn'])) {
$config['person_fn'] = function() {
return $this->person();
};
}
$rollbar = new \Rollbar\Rollbar;
$rollbar->init($config);
$logger = new \Rollbar\Laravel\RollbarLogHandler($rollbar->logger(), app());
$handler = new \Monolog\Handler\PsrHandler($logger);
return new \Monolog\Logger('rollbar', [$handler]);
}
あとはconfing/logging.phpへchannelとして登録するだけでRollbarへのログが送信されます。
全ての実装はGitHubで公開していますので利用してみてください。

[Laravel] BladeのComponent Aliasesを便利に使う方法
Laravel5.6がリリースされましたが、目玉の一つとしてBladeコンポーネントが大きくアップデートされました。
Bladeをより便利に使うために、コンポーネントとしての利用方法を紹介します。
Component Aliases
コンポーネント化されたviewファイルの呼び出しにエイリアスが利用できます。
以下のファイルを作成します。
<!-- /resources/views/components/alert.blade.php -->
<div class="alert alert-danger">
<div class="alert-title">{{ $title }}</div>
{{ $slot }}
</div>
@includeを利用した呼び出し
引数に/resources/views以下のパス(ドット)と、Blade内で利用する変数を配列で渡します。
@include('components/alert, ['title' => 'タイトル', 'slot' => 'メッセージ'])
@componentを利用した呼び出し
引数に/resources/views以下のパス(ドット)を渡して、@endcomponentの間に記述した内容が$slotとして展開されます。
また、@slot()を記述することにより、引数に渡した文字列の変数に展開されます。
@includeの呼び出しに対して、より動的な値や、HTMLタグを用いることが用意になります。
@component('alert')
@slot('title')
タイトル
@endslot
メッセージ
@endcomponent
Blade::component()を利用した呼び出し
作成したBladeファイルにオリジナルの名前をつけて利用することができるようになります。
サービスプロバイダ等で登録することにより、より柔軟な利用が可能になりました。
use Illuminate\Support\Facades\Blade;
Blade::component('components.alert', 'alert');
上記によりエイリアスとして登録され、@alertディレクティブとして/resources/views/components/alert.blade.phpが利用可能になります。
@alert(['title' => 'タイトル'])
メッセージ
@endalert
Blade::include()を利用した呼び出し
Blade::component()と似ていますが、こちらもエイリアスを利用した呼び出しが可能になります。
ただしこちらは@includeをより簡単にしたもので、slotを利用することは出来ません。
<!-- /resources/views/includes/input.blade.php -->
<input type="{{ $type ?? 'text' }}">
サービスプロバイダで登録します。
use Illuminate\Support\Facades\Blade;
// ドット記法の最後の単語がエイリアスとして登録されます
Blade::includes('includes.input');
// オリジナルのエイリアスを指定することも出来ます
Blade::include('includes.input', 'textinput');
登録が終われば、@inputディレクティブとして/resources/views/includes/input.blade.phpが利用可能になります。
@input(['type' => 'email'])
番外編
特定の条件によって、表示の有無を切り替える必要があることもあります。
@ifディレクティブやPolicyを利用することでコントロール可能ですが、@includeWhenディレクティブの利用でよりスマートに記述できます。
// @ifを利用した書き方
@if ($user->ownsPost($post)
@include('post.edit', ['post' => $post])
@endif
// @includeWhenを利用した書き方
@includeWhen($user->ownsPost($post), 'post.edit', ['post' => $post])
Blade Component Aliasesをより詳しく学ぶためにも、公式のドキュメントを確認して起きましょう。

[Laravel] 5.6.12がリリースされました
Laravelのバージョン5.6.12がリリースされました。
blade:cacheコマンドが追加されました。
事前にBladeテンプレートをプリコンパイルすることで表示速度が向上します。
$ php artisan blade:cache
Blade templates cached successfully!
詳細については追加されたIlluminate\Foundation\Console\BladeCacheCommandを参照してください。

[Laravel] 5.6.10がリリースされました
Laravelのバージョン5.6.10がリリースされました。更新された機能について確認していきます。
Added
1. Blueprint::dropMorphs()メソッドが追加されました
Added Blueprint::dropMorphs() (#23431)
2. メール送信時にStorageからファイルを添付できるようになりました
FileSystemを利用しているS3等のストレージからファイルを添付できます。
// 今までのファイル添付
$message->attach($pathToFile, array $options = []);
// ストレージから添付 - 5.6.10で追加
$message->attachFromStorage($path, $name = null, array $options = []);
// ストレージから添付 (ディスク指定) - 5.6.10で追加
$messaeg->attachFromStorageDisk($disk, $path, $name = null, array $options = []);
attachFromStorageの場合は、config/filesystems.phpでdefaultに指定しているストレージが利用されます。
Added Mailable::attachFromStorage() methods (@0fa361d)
3. Query BuilderにorWhereDay、orWhereMonth、orWhereYearが追加されました
// 2018-03-10もしくは2018-03-11に作成されたレコード
$query->whereDay('created_at', '2018-03-10');
$query->orWhereDay('created_at', '2018-03-11');
// ...
Added orWhere*() builder methods for day, month and year (#23449 )
Changed
1. stub作成じのドロップダウンリンクにv-pre属性を含むように変更されました
Added v-pre to dropdown link in app.stub (@98fdbb0)
2. JSON_PARTIAL_OUTPUT_ON_ERRORが発生した場合のエラーメッセージが変更されました
Handle more JSON errors gracefully when JSON_PARTIAL_OUTPUT_ON_ERROR is set (#23410, @972b82a)
3. ログ設定にbubble、permission、lockingが指定できるように変更されました
loggingにsingle、もしくはdailyを指定する場合にこのオプションが使用できます。
confing/logging.phpへ以下のように追加しましょう。
'channels' => [
// ...
'single' => [
// ...
'bubble' => true,
'permission' => 0775,
'locking' => false,
],
'daily' => [
// ...
'bubble' => true,
'permission' => 0775,
'locking' => false,
],
// ...
],
4. Request::validate()の戻り値がStr::contains()に変更されました
Use Str::contains() instead of str_contains() (@ae4cb28)
Fixed
1. unique()バリデーションでkeyが重複する場合に値が失われる問題を修正しました
Fixed unique() call in Validator::validate() (#23432)
2. Carbon利用時の処理が修正されました
Fix for Carbon 1.24.0 (@67d8a4b)
Release v5.6.10 · laravel/framework · GitHub

[Laravel] 5.6.9がリリースされました
Laravelのバージョン5.6.8、5.6.9がリリースされました。更新された機能について確認していきます。
Changed (5.6.9)
セッションの再発行時 (Session::regenerate) にトークン情報も再設定されるようになりました。
また、潜在的なXSSに対する修正により、Bootstrapのscaffoldingが変更されました。
JS Frameworks, Server Side Rendering, and XSS – Taylor Otwell – Medium
<a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
{{ Auth::user()->name }} <span class="caret"></span>
</a>
v-pre属性を付与することにより既存のコードを修正できます。
Regenerate token when regenerating the session (@20e8419)
Fixed (5.6.9)
Fixed an issue with resources when loading a single merge value with an associative array (#23414)
Release v5.6.9 · laravel/framework · GitHub
Added (5.6.8)
MySQLのsounds likeが利用可能になりました。
$builder->select('*')->from('users')->where('name', 'sounds like', 'John Doe');
Added support for MySQL’s sounds-like operator (#23351)
リクエスト数超過時の例外にIlluminate\Http\Exceptions\ThrottleRequestsExceptionが投げられるようになりました。
Added ThrottleRequestsException exception (#23358)
Bladeエンジンに@dumpディレクティブが追加されました。
Added @dump Blade directive (#23364)
Collection::whereInstanceOfMethod()メソッドが追加されました。
メッソド名の通り、指定のクラスをコレクションからフィルタリングできます。
$c = new Collection([new stdClass, new stdClass, new Collection, new stdClass]);
$this->assertCount(3, $c->whereInstanceOf(stdClass::class));
Added Collection::whereInstanceOfMethod() (@78b5b92)
Dispatchable::dispatchNow()メソッドが追加されました。
Illuminate\Contracts\Bus\Dispatcher\Dispatchableトレイトを利用する場合にも同期的にJOB実行が可能になりました。
Added Dispatchable::dispatchNow() (#23399)
Changed (5.6.8)
DatabaseNotificationを使用する際に発行される通知データを変更可能になりました。
\Illuminate\Notifications\Channels\DatabaseChannel::buildPayload()メソッドをOverwriteすることで、Model毎の通知データをカスタマイズできます。
/**
* Build an array payload for the DatabaseNotification Model.
*
* @param mixed $notifiable
* @param \Illuminate\Notifications\Notification $notification
* @return array
*/
protected function buildPayload($notifiable, Notification $notification)
{
return [
'id' => $notification->id,
'type' => get_class($notification),
'data' => $this->getData($notifiable, $notification),
'read_at' => null,
];
}
Allow extension of DatabaseNotification model attributes (#23337)
認証系のscaffoldingがi18nに対応しました。
make:authコマンドで生成されるBladeファイルの全てが修正されました。
下記はresources/views/auth/login.blae.phpのstubファイルです。
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Login') }}</div>
<div class="card-body">
<form method="POST" action="{{ route('login') }}">
@csrf
<div class="form-group row">
<label for="email" class="col-sm-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ old('email') }}" required autofocus>
@if ($errors->has('email'))
<span class="invalid-feedback">
<strong>{{ $errors->first('email') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-group row">
<label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control{{ $errors->has('password') ? ' is-invalid' : '' }}" name="password" required>
@if ($errors->has('password'))
<span class="invalid-feedback">
<strong>{{ $errors->first('password') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-group row">
<div class="col-md-6 offset-md-4">
<div class="checkbox">
<label>
<input type="checkbox" name="remember" {{ old('remember') ? 'checked' : '' }}> {{ __('Remember Me') }}
</label>
</div>
</div>
</div>
<div class="form-group row mb-0">
<div class="col-md-8 offset-md-4">
<button type="submit" class="btn btn-primary">
{{ __('Login') }}
</button>
<a class="btn btn-link" href="{{ route('password.request') }}">
{{ __('Forgot Your Password?') }}
</a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
Made auth scaffolding translatable (#23342)
Eloquent ModelのgetForeignKey()(リレーションを作成する際に外部キーを取得するメソッド)の処理が変更されました。
Str::snake(class_basename($this)).'_'.$this->primaryKeyからStr::snake(class_basename($this)).'_'.$this->getKeyName()変更されました。
これによってgetKeyName()をOverwrite可能になり、継承先のモデルからでも外部キーの変更が可能になりました。
Use getKeyName() in getForeignKey() (#23362)
FileSystemにてファイルやディレクトリを複数取得する際のソート順が名前順に変更されました。
Sort FileSystem files and directories by name (#23387)
Validatorのvalidate()メソッドが検証済みの値を返却するように変更されました。
Return validated data from Validator::validate() (#23397, @3657d66)
Fixed
serveコマンドが修正されました
Fixed serve command escaping (#23348)
Query BuilderのwithCount()メソッドの実装が移動されました。
Fixed an issue with multiple select statements in combination with withCount() (#23357)
Conditional loadの方法を修正しました。
Fixed conditional loading issues (#23369)
Model Factoryで配列を指定した場合の挙動が修正されました。
Prevent considering arrays as callable while building model factories (#23372)
Composerでtighenco/collectがコンフリクトしていた問題を修正しました。
Move tightenco/collect to Composer’s conflict (#23379)
View内でループの引数にTraversableオブジェクトを渡した際の挙動が修正されました。
Set up loop variable correctly on all Traversable objects (#23388, @49770ec)
Pivot Modelで値をフィルタリングする処理が修正されました。
Removed attribute filling from pivot model (#23401
Release v5.6.8 · laravel/framework · GitHub

[Laravel] Pwnedを使って安全なパスワードを利用する
サービスを利用する際にアカウントに設定する「パスワード」はとても重要です。他のサービスと同じパスワードの使い回しや、簡単なパスワードを利用したことによるアカウントの乗っ取り(不正アクセス)の危険があります。
Pwned Passwordsは過去に漏洩した膨大なデータを収集して、利用するパスワードが過去に何らかの形で漏洩したパスワードかどうかを確認できます。
このサービスをLaravelのユーザー登録時のValidationとして使ってみましょう。
パッケージのインストール
valorin/pwned-validatorをインストールします。
$ composer require valorin/pwned-validator
Laravelの5.4未満を利用している場合は下記をconfig/app.phpへ追記します。
'providers' => [
Valorin\Pwned\ServiceProvider::class,
],
バリデーションの設定
Laravelの認証システムを利用できるようにしておきましょう。
$ php artisan make:auth
App\Http\Controllers\Auth\RegisterControllerのvalidatorメソッドのpasswordにpwnedルールを追加します。
return Validator::make($data, [
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6|pwned|confirmed',
]);
/registerのURLへアクセスして、パスワード情報に12345678といった簡易なものを入力してみましょう。バリデーションに引っかかります。
※ 作成時点では12345678のパスワードは過去に2,680,521回漏洩しています。
バリデーションの際のメッセージを変更する場合はresources/lang/{言語}/validation.phpに追加しましょう。
また、pwnedのデフォルトの漏洩回数は1回です。
この値を変更する場合は下記のように記述します。
// 100回以上漏洩しているパスワードをチェック
'password' => 'required|string|min:6|pwned:100|confirmed',
Laravelの5.5で追加されたRuleクラスでの利用も可能です。
// 150回以上漏洩しているパスワードをチェック
'password' => ['required', 'string', 'min:6', new \Valorin\Pwned\Pwned(150), 'confirmed'],