[Laravel] 5.7.9がリリースされました
laravel/frameworkのバージョン5.7.9がリリースされました。更新された機能について確認していきます。
Added
1. generatorコマンドでオリジナルのUserProviderが利用できるようになりました #25681
2. 401エラー時のviewが追加されました #26002
3. Inspiringに名言が追加されました #25968
4. Mailableのrender()メソッドがlocaleを評価するようになりました #25990
5. Notificationにいくつかのメタデータが追加されました 477273c
6. PendingResourceRegistrationクラスにMacroableトレイとが追加されました #25947
7. TestResponseクラスに assertSessionDoesntHaveErrors()メソッドが追加されました #25949, 3005706
8. presetコマンド実行時に--optionオプションでカスタマイズが可能になりました #25930
詳しい変更については以下を確認してください。
Release v5.7.9 · laravel/framework · GitHub
[Laravel] 5.7.8がリリースされました
laravel/frameworkのバージョン5.7.8がリリースされました。更新された機能について確認していきます。
Added
1. migrate:freshに--stepオプションが追加されました #25897
2. モデルのdestroyメソッドにCollectionが渡せるようになりました #25878
3. Pivotクラスの処理がAsPivotトレイトに以降されました #25851
詳しい変更については以下を確認してください。
Release v5.7.8 · laravel/framework · GitHub
[Laravel] 5.7.7がリリースされました
laravel/frameworkのバージョン5.7.7がリリースされました。更新された機能について確認していきます。
Added
1. Gate::before()にコールバックの配列が渡せるようになりました #25817
以下のように呼び出せるようになりました。
Gate::before([$object, 'method'])
2. メール送信時のロケールについてモデルベースでのロケール設定が可能になりました #25752
\Illuminate\Contracts\Translation\HasLocalePreferenceインターフェイスを使用するモデルにおいて、メール送信時にpreferredLocale()メソッドが評価されます。
use Illuminate\Contracts\Translation\HasLocalePreference;
class User extends Model implements HasLocalePreference
{
public function preferredLocale()
{
return $this->locale;
}
}
$user = User::create([
'email' => '[email protected]',
'locale' => 'de',
]);
尚、以下のように直接ロケールを指定している場合はこちらが優先されます。
Mail::to($user)->locale('en')->send(new TestMail());
3. Seerder実行時に常に実行結果が出力されるようになりました #25872
4. PostgreSQLでJSON型のカラムの更新が可能になりました #25797
5. データベースのカラムをJSON型へ変更する際に厳密に型指定が可能になりました #25741
6. Queueでクロージャを実行できるようになりました #25777
7. 暗号化のアルゴリズムの指定をスキップするプロパティが追加されました #25468, 5fd4b89
古いバージョンのbycrpt等を使用していた場合、5.7にアップデートした際にログインできなくなる問題が解決されています。
8. Queueでペイロードをフックできるようになりました f68cbe
9. 認可(can)のパラメーターに文字列が渡せるようになりました #25763
詳しい変更については以下を確認してください。
Release v5.7.7 · laravel/framework · GitHub
[Laravel] 5.7.6がリリースされました
laravel/frameworkのバージョン5.7.6がリリースされました。更新された機能について確認していきます。
Added
1. EloquentモデルでmorphToメソッドを利用したリレーションのロードに、取得するカラムを指定できるようになりました #25662
Eager Loadingの際に取得したいカラムを渡します。
Comment::with('commentable:id,title')->get();
# expected
select "id", "title" from "posts" where "posts"."id" in (?)
詳しい変更については以下を確認してください。
Release v5.7.6 · laravel/framework · GitHub
[Laravel] 5.7.5がリリースされました
laravel/frameworkのバージョン5.7.5がリリースされました。更新された機能について確認していきます。
Added
1. \Illuminate\Mail\MailableでViewへ渡すデータにコールバックが渡せるようになりました (7dc3d8d35ad8bcd3b18334a44320e3162b9f6dc1)
以下のメソッドが追加され、Viewデータをビルドするときにデータがマージされます。
// \Illuminate\Mail\Mailable
/**
* Register a callback to be called while building the view data.
*
* @param callable $callback
* @return void
*/
public static function buildViewDataUsing(callable $callback)
{
static::$viewDataCallback = $callback;
}
詳しい変更については以下を確認してください。
Release v5.7.5 · laravel/framework · GitHub
[Laravel] Email Verification(メールアドレスの確認機能)の使い方とカスタマイズについて
先日のLaravel5.7のリリースで新しく追加されたEmail Verificationがとても便利ですので紹介します。
今までのLaravelでは、フレームワーク内に認証機能が実装されており、これを有効にすることで簡単にログイン機能等を利用することができました。
デフォルトの挙動では、ユーザーの新規作成(/registerページ)後にそのままログインが可能になるというフローでした。
認証付きのサービス等でよく見る、ユーザーの新規作成時に登録されたメールアドレスが正確かどうかを確認するフロー(本登録メール等)をはさみたい場合には、自前で実装するかサードパーティーのパッケージを利用する必要がありました。(josiasmontag/laravel-email-verificationl等)
メールアドレスが正確かどうかの確認は、サービス上でユーザーとのやりとりが発生する場合においてとても重要です。
この機能がついにLaravelで実装されました。
Email Verificationの利用方法
ドキュメントに書いてある通り、使い方はとても簡単です。
App\UserモデルへIlluminate\Contracts\Auth\MustVerifyEmailインターフェイスと、Illuminate\Auth\MustVerifyEmailトレイトを追加します。
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail as MustVerifyEmailContract;;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Auth\MustVerifyEmail;
class User extends Authenticatable implements MustVerifyEmailContract
{
use Notifiable, MustVerifyEmail;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
}
認証ルートの作成は今まで通りphp artisan make:authコマンドを実行し、routes/web.phpファイルに認証のためのルートが追加されます。
追加されたAuth::routes();に引数を渡すように変更します。
// 変更前
// Auth::routes();
// 変更後
Auth::routes(['verify' => true]);
Tips
Auth::routes()メソッド(AuthファサードでIlluminate\Routing\Routerクラスのauthメソッドが呼ばれる)の処理が以下のように変更されてメールアドレス確認用のルーティングが追加されています。
/**
* Register the typical authentication routes for an application.
*
* @param array $options
* @return void
*/
public function auth(array $options = [])
{
// Authentication Routes...
$this->get('login', 'Auth\LoginController@showLoginForm')->name('login');
$this->post('login', 'Auth\LoginController@login');
$this->post('logout', 'Auth\LoginController@logout')->name('logout');
// Registration Routes...
$this->get('register', 'Auth\RegisterController@showRegistrationForm')->name('register');
$this->post('register', 'Auth\RegisterController@register');
// Password Reset Routes...
$this->get('password/reset', 'Auth\ForgotPasswordController@showLinkRequestForm')->name('password.request');
$this->post('password/email', 'Auth\ForgotPasswordController@sendResetLinkEmail')->name('password.email');
$this->get('password/reset/{token}', 'Auth\ResetPasswordController@showResetForm')->name('password.reset');
$this->post('password/reset', 'Auth\ResetPasswordController@reset')->name('password.update');
// Email Verification Routes...
if ($options['verify'] ?? false) {
$this->emailVerification();
}
}
後は認証が確認なルートのmiddlewareにverifiedを指定するだけです。(すべての認証ルートに適用する場合にはauthミドルウェアをverifiedミドルウェアに置き換えるだけです)
Route::middleware(['verified'])
->group(function() {
Route::get('example', function() {
return 'Access';
});
});
Laravel 5.6からアップデートした際には以下の作業が必要です
新しくLaravel5.7をインストールした場合には不要ですが、それ以前のバージョンからアップデートを行った場合には下記作業を行ってください。
1. VerificationControllerをapp/Http/Controllers/Auth/VerificationController.phpへ配置
2. app/Http/Kernel.phpの$routeMiddlewareへIlluminate\Auth\Middleware\EnsureEmailIsVerifiedを追加
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* @var array
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
3. app/Providers/EventServiceProvider.phpにIlluminate\Auth\Listeners\SendEmailVerificationNotificationイベントを追加
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Event;
use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
Registered::class => [
SendEmailVerificationNotification::class,
],
];
/**
* Register any events for your application.
*
* @return void
*/
public function boot()
{
parent::boot();
//
}
}
認証周りのイベントについてはこちらで説明しています。
4 database/migrations/2014_10_12_000000_create_users_table.phpにemail_verified_atの追加
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}
設定ができたら、/registerへアクセスして新規登録を行いましょう。
登録したメールアドレスへ認証メールが届きます。
確認メールのカスタマイズ
確認メールの送信はIlluminate\Auth\Notifications\VerifyEmailクラスで行います。
標準では英語の文面ですが、メールの構文にはIlluminate\Translation\Translatorクラスが使用されているため、オリジナルの言語ファイルを設置することにより文面のカスタマイズが行えます。
以下のファイルをapp/resources/lang/ja.jsonとして保存してください。
{
"Hello!": "こんにちは",
"Verify Email Address": "メールアドレスの確認",
"Please click the button below to verify your email address.": "以下をクリックして、メールアドレスの確認を行ってください。",
"If you did not create an account, no further action is required.": "このメールの内容に身に覚えがない場合は、このまま破棄してください。",
"Regards": "宜しくお願い致します",
"If you’re having trouble clicking the \":actionText\" button, copy and paste the URL below\ninto your web browser: [:actionURL](:actionURL)": "\":actionText\" ボタンが機能しない場合は, こちらのURLをブラウザにコピーして貼り付けてください: [:actionURL](:actionURL)"
}
config/app.phpのlocaleをjaに指定している場合に、設定した日本語でメールが送られてきます。
Tips
メールの送信そのものをオリジナルにカスタマイズする場合には、toMailUsing()メソッドで送信処理をコールバックで渡すことができます。
app/Providers/AppServiceProvider.php等でオリジナルのコールバックを指定しましょう。
<?php
namespace App\Providers;
use Illuminate\Auth\Notifications\VerifyEmail;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
VerifyEmail::toMailUsing(function ($notifiable) {
$verifyUrl = URL::temporarySignedRoute(
'verification.verify', now()->addMinutes(60), ['id' => $notifiable->getKey()]
);
return (new MailMessage())
->subject('Your subject')
->line('Whatever you like')
->action('Verify it', $verifyUrl);
});
}
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
}
[Laravel] 5.7がリリースされました
laravel/frameworkのバージョン5.7がリリースされました。更新された機能について確認していきます。
Laravel 5.7では以下の用な更新が行われています。
Laravel Novaへの対応
ユーザーのメールアドレスの検証機能の追加
GateやPolicyといった認証に関わる部分でのゲストユーザをサポートする機能の追加
Artisanコマンドのテスト方法の改善
Symfonyを使用したDump Serverの統合
Notificationのローカライズ対応
その他のバグの修正、およびユーザビリティの向上
メールアドレスの検証
Laravel 5.7では、フレームワークに含まれている認証用テンプレートにオプションのメールアドレスの検証が追加されました。
この機能に対応するために、フレームワークに含まれているデフォルトのユーザーテーブルのmigrationにemail_verified_atタイムスタンプ列が追加されています。
新しく登録したユーザーにメールアドレスの検証を促すには、UserモデルにMustVerifyEmailインターフェイスを設定する必要があります。
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable implements MustVerifyEmail
{
// ...
}
UserモデルにMustVerifyEmailインターフェイスが設定されると、新しく登録されたユーザーには、署名付きの確認リンクが記載されたメールが送信されます。
このリンクがクリックされると、Laravelは検証時間を自動的にデータベースに記録します。
verifiedミドルウェアがデフォルトのアプリケーションのHTTPカーネルに追加されました。このミドルウェアは、検証されたユーザーのみを許可することができます。
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
詳細についてはこちらをご確認ください
ゲストユーザーのGate/Policy
Laravelの以前のバージョンでは、未認証GateとPolicyはアプリケーションが自動的にfalseを返しました。ただしOptional型のタイプヒンティングを宣言するか、nullのデフォルト値を指定することで、ゲストが認可を通過できるようになりました。
Gate::define('update-post', function (?User $user, Post $post) {
// ...
});
Symfony Dump Server
Laravel 5.7は、 beyondcode/laravel-dump-serveのパッケージを使用してSymfonyのDump Serverと統合されました。利用するには、Artisanコマンドのdump-serverを実行します。
php artisan dump-server
Dump Serverが起動すると、ダンプするすべての呼び出しは、ブラウザーではなくコンソール・ウィンドウに表示され、HTTP応答出力をマ待つこと無く値を検査することができます。
Notificationのローカリゼーション
Laravelでは、現在の言語以外のロケールで通知を送信できるようになり、通知がキューに送る場合でもこのロケールを指定可能です。
これを実現するために、Illuminate\Notifications\Notificationクラスは、目的の言語を設定するためのlocale()メソッドが追加されました。通知がフォーマットされると、アプリケーションはこのロケールに変更され、フォーマットが完了すると以前のロケールに戻ります。
$user->notify((new InvoicePaid($invoice))->locale('es'));
複数の通知エントリのローカライズは、Notificationファサードを介して行うこともできます。
Notification::locale('es')->send($users, new InvoicePaid($invoice));
Artisanコマンドのテスト
Laravel 5.7では、expectsQuestionメソッドを使用してArtisanコマンドのユーザー入力を簡単にモック化できます。
また、assertExitCodeおよびexpectsOutputメソッドを使用して、Artisanコマンドによって出力されると予想される終了コードおよびテキストを指定することもできます。
たとえば、次のArtisanコマンドを例にします。
Artisan::command('question', function () {
$name = $this->ask('What is your name?');
$language = $this->choice('Which language do you program in?', [
'PHP',
'Ruby',
'Python',
]);
$this->line('Your name is '.$name.' and you program in '.$language.'.');
});
expectsQuestion、expectsOutput、およびassertExitCodeメソッドを使用する次のテストでこのコマンドをテストできます。
/**
* Test a console command.
*
* @return void
*/
public function test_console_command()
{
$this->artisan('laracon')
->expectsQuestion('What is your name?', 'Taylor Otwell')
->expectsQuestion('Which language do you program in?', 'PHP')
->expectsOutput('Your name is Taylor Otwell and you program in PHP.')
->assertExitCode(0);
}
URL Generatorがコールバックに対応しました
LaravelのURLジェネレータは、文字列を受け入れるだけでなく、コントローラアクションのURLを生成する際に、callableな構文を受け入れるようになりました。
action([UserController::class, 'index']);
Paginator Links
Laravel 5.7では、ページネーションの両側に表示されるリンクの数を制御できます。
デフォルトでは、プライマリページリンクの各サイドに3つのリンクが表示されます。
ただし、onEachSideメソッドを使用してこの数を制御できます。
{{ $paginator->onEachSide(5)->links() }}
Filesystem Read / Write Streams
LaravelのFlysystemで、readStreamメソッドとwriteStreamメソッドが利用可能になりました。
Storage::disk('s3')->writeStream(
'remote-file.zip',
Storage::disk('local')->readStream('local-file.zip')
);
詳しい内容については以下を確認してください。
Release Notes - Laravel - The PHP Framework For Web Artisans
[Larevel] Seederをより使いやすくする
LaravelではSeederを利用したデータの登録が用意されており、これをより使いやすくインタラクティブにする方法がとても良かったので紹介します。
ユーザーには3つの権限administrator、writer、readerのいずれかに属するものとし、これをSeeder実行時に指定するサンプルです。
migrationの編集
Laravelインストール時に用意されているdatabases/migrations/2014_10_12_000000_ceate_users_table.phpを編集して利用します。
下記のように権限に関するroleカラムを追加してください。
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->enum('role', ['administrator', 'writer', 'reader'])->default('reader');
$table->rememberToken();
$table->timestamps();
});
}
編集後にphp artisan migratoinコマンドでマイグレーションを実行しておきましょう。
Userモデルの編集
作成したroleカラムに関する処理を追加します。
// app/User.php
public function withRole($role)
{
$this->role = $role;
$this->save();
return $this;
}
Seederの作成
今回の肝の部分ですが、実行するSeederを作成しておきます。
php artisan make:seeder UserSeeder
Seeder created successfully.
作成したSeederを下記のように編集します。
<?php
use Illuminate\Database\Seeder;
class UserSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
factory(\App\User::class)
->create()
->withRole($this->command->choice(
'What role is the user?', [
'administrator',
'writer',
'reader'
]
));
}
}
コマンドクラスのchoiceメソッドを利用して、withRole()メソッドへ渡す引数の指定を可変に出来ます。
Seederコマンドを実行して動作を確認してみましょう。
php artisan db:seed --class=UserSeeder
What role is the user?:
[0] administrator
[1] writer
[2] reader
コンソール上に権限を指定するインターフェイスが表示されました。各種数字を入力することで、簡単に権限の付与が可能になります。
Caleb Porzioさんのツイート: "🌱💧 Pro Tip: make your database seeders more user-friendly and interactive with Laravel's command interface 💧🌱 ... endless possibilities… https://t.co/MYD6EGmYAk"
[Laravel] 5.6.30がリリースされました
laravel/frameworkのバージョン5.6.29がリリースされました。このリリースはセキュリティーに関する内容で、すべてのユーザーへ即時アップグレードするよう推奨されています。
要約すると、.env内のAPP_KEYを第三者が知っている場合に、この対策を行う必要があります。
アップデートの内容について
この脆弱性は、アプリケーションの暗号化キー(APP_KEY環境変数)に悪意のあるユーザーがアクセスした場合にのみ悪用される可能性があります。
通常、アプリケーションのユーザーがこの値にアクセスすることはできません。
ただし、暗号化キーにアクセスした第三者は、キーを使用してアプリケーションを攻撃することができます。
暗号化キーが悪意のあるユーザーの手に入ると思われる理由がある場合は、そのキーを新しい値に変更する必要があります。
Cookie Serialization
Laravel 5.6.30は、クッキー値のシリアル化/シリアル化解除をすべて無効にします。
すべてのLaravel Cookieは暗号化されて署名されているため、通常、クライアントの改ざんから安全とみなされます。
しかし、アプリケーションの暗号鍵が悪意のある人の手に入ると、その当事者は暗号鍵を使用してクッキー値を作成し、脆弱性を悪用してアプリケーション内の任意のクラスメソッドを呼び出すなどのPHPオブジェクトの直列化/直列化解除を継承することができます。
すべてのCookie値でシリアル化を無効にすると、アプリケーションのすべてのセッションが無効になり、ユーザーはアプリケーションに再度ログインする必要があります。
さらに、アプリケーションが設定している他の暗号化されたCookieには無効な値が含まれます。
このため、アプリケーションに追加のロジックを追加して、カスタムCookie値が予期した期待値リストと一致することを検証することができます。さもなければ、あなたはそれらを捨てるべきです。
Configuring Cookie Serialization
この脆弱性はアプリケーションの暗号化キーにアクセスすることなく悪用することはできません。
暗号化されたCookieのシリアル化を再び有効にして、アプリケーションをこれらの変更と互換性を持たせる方法を提供しました。
Cookieのシリアル化を有効または無効にするには、App\Http\Middleware\EncryptCookiesミドルウェアのserializeプロパティを変更することができます。
/**
* Indicates if cookies should be serialized.
*
* @var bool
*/
protected static $serialize = true;
尚、すでに第三者がAPP_KEYを知っている場合は、serializeプロパティを変更する前にAPP_KEYの再設定が必要となります。
Upgrade Guide - Laravel - The PHP Framework For Web Artisans
[Laravel] 5.6.29がリリースされました
laravel/frameworkのバージョン5.6.29がリリースされました。更新された機能について確認していきます。
Added
1. Observerのstubにrestored()とforceDeleted()が追加されました (#40ba2ee)
2. UploadedFile::getContents()が追加されました (#24924)
ファイルのアップロードを行う際に、ファイルの内容の確認が必要な場合などに利用します。
3. FactoryBuilderで名前付きで定義したFactoryを呼び出す際のエイリアスが追加されました (#24937)
state()メソッドが追加されてエイリアスで呼べるようになりました。
// ModelFactory
$factory->define(App\Issues::class, function (Faker\Generator $faker) {
return [
'subject' => $faker->sentence(5),
'description' => $faker->text(),
];
});
$factory->defineAs(App\Issues::class, 'completed', function ($faker) use ($factory) {
$issue = $factory->raw(App\Issues::class);
return array_merge($issue, ['completed' => true]);
});
// Use Faker
$listing = factory(App\Issues::class)->state('completed')->create();
詳しい変更については以下を確認してください。
Release v5.6.29 · laravel/framework · GitHub