LoginSignup
9
6

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-11-24

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');
9
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
6