Help us understand the problem. What is going on with this article?

Laravel(5.7)のパスワードリセットや確認メール機能をAPIからキックする

More than 1 year has passed since last update.

Laravelではmake:authすれば認証関連の基本的な機能が自動生成されます。
が、SPAとかだと、それらをAPI経由で叩く必要があるので、その方法を試してみます。

特に、

  • パスワードリセットメールの送信
  • 登録時の確認メール(5.7から)

機能について見てみます。

方法の検討

どちらの機能も独自のControllerを作成して実装すればよいのですが、ここでは、make:authで生成されるapp/Http/Controllers/Authをapp/Http/Controllers/Apiとしてコピーし利用してみます。

パスワードリセット

パスワードリセットメールはWebではAuth/ForgotPasswordController.phpのsendResetLinkEmail()にて行われていますので、それをAPIで叩いてやります。ついでに戻り値をjsonにしてやります。

Validationエラーの場合もHTMLベースの値が帰るのでapp/Exceptions/Handler.phpか独自のRequestFormを作成して処理すればいいでしょう。

Api/ForgotPasswordController.php

<?php

+namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;

+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Password;

class ForgotPasswordController extends Controller
{
    use SendsPasswordResetEmails;

    public function __construct()
    {
        $this->middleware('guest');
    }

+    public function sendResetLinkEmail(Request $request)
+    {
+        $this->validateEmail($request);

+        $response = $this->broker()->sendResetLink(
+            $request->only('email')
+        );

+        return $response == Password::RESET_LINK_SENT
+            ? response()->json(['message' => 'Reset link sent to your email.', 'status' => true], 201)
+            : response()->json(['message' => 'Unable to send reset link', 'status' => false], 401);
+    }
}

routes/api.php

ルートを追加します。そもそもログインできていないのでguestで処理できるようにしておきます。

Route::post('password/email', 'Api\ForgotPasswordController@sendResetLinkEmail')->name('api.password.email');

動作確認

http://localhost:8000/api/password/email にemailをPOSTしてやれば(登録済みなら)指定のアドレスにメールが届くはずです。

確認メールの送信(というか登録)

登録時に確認メールを送信する場合です。Userに対して確認メール設定を行っているものとします(いちおう方法は後述)。

Api/RegisterController.php

WebではAuth/Api/RegisterController.phpのregister()でユーザー登録を受けています。
なので、Api/RegisterController.phpのregister()をオーバーライドします。

passwordのvalidationからcomfirmを外しています。

<?php

namespace App\Http\Controllers\Api;

use App\User;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Auth\RegistersUsers;

+use Illuminate\Http\Request;
+use Illuminate\Auth\Events\Registered;

class RegisterController extends Controller
{
    use RegistersUsers;

    public function __construct()
    {
        $this->middleware('guest');
    }

    protected function validator(array $data)
    {
        return Validator::make($data, [
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
+            'password' => ['required', 'string', 'min:6'],
        ]);
    }

    protected function create(array $data)
    {
        return User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => Hash::make($data['password']),
        ]);
    }

+    public function register(Request $request)
+    {
+        $this->validator($request->all())->validate();

+        event(new Registered($user = $this->create($request->all())));

+        return $user ? response()->json(['user' => $user, 'status' => true], 201)
+                     : response()->json(['user' => null, 'status' => false], 401);
+    }
}

各種エラー処理についてはパスワードリセットと同様、独自のFormRequestを作成するなどして対応したほうがいいです。

Route

ルートを追加します。新規登録なのでguestで処理できるようにしておきます。

api.php
Route::post('register', 'Api\RegisterController@register')->name('api.register');

動作確認

http://localhost:8000/api/register にname, email, passwordをPOSTして登録できることを確認します。

補足

email verify機能の利用方法です。

User.php

モデルを下記のように変更します。

User.php
<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Laravel\Passport\HasApiTokens;

+class User extends Authenticatable implements MustVerifyEmail
{
    use Notifiable;
    use HasApiTokens;

    protected $fillable = [
        'name', 'email', 'password',
    ];

    protected $hidden = [
        'password', 'remember_token',
    ];
}

Route

必要なルートを追加します。SPA等で利用する場合は特に画面遷移などは必要ありません。

Auth::routes(['verify' => true]);

Route::get('/home', 'HomeController@index')->name('home')->middleware('verified');
Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away