目次
Laravelの記事一覧は下記
PHPフレームワークLaravelの使い方
Laravelバージョン
動作確認はLaravel Framework 7.19.1で行っています
前提条件
eclipseでLaravel開発環境を構築する。デバッグでブレークポイントをつけて止める。(WindowsもVagrantもdockerも)
本記事は上記が完了している前提で書かれています
プロジェクトの作成もapacheの設定も上記で行っています
Laravelでデータベースを扱う準備をする
Laravelでテーブル作成
Laravelで初期データ投入
Laravelでデータベースを操作する(Eloquent編)
本記事は上記ので作成したデータベースとレコード、PHPファイルを使用します
認証に必要なソース生成
コマンドラインで
cd sample
composer require tymon/jwt-auth
xdebugの設定をしているとeclipseが実行していいですかというプロンプトを出すのでOKを押します
コマンドラインで
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
eclipseプロジェクトを右クリック→リフレッシュ
/sample/config/jwt.phpが現れます
コマンドラインで
php artisan jwt:secret
eclipseプロジェクトを右クリック→リフレッシュ
/sample/.envにJWT_SECRETが記載されます
Model修正
/sample/app/Models/User.php修正
(1) use文追記
use Tymon\JWTAuth\Contracts\JWTSubject;
追記
(2) implementsにJWTSubject追加
class User extends Authenticatable implements MustVerifyEmail , JWTSubject
(3) メソッド追加
public function getJWTIdentifier()
{
return $this->getKey();
}
public function getJWTCustomClaims()
{
return [];
}
auth.php修正
/sample/config/auth.php修正
guards->apiを修正
‥‥
'guards' => [
‥‥
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
],
‥‥
Controller
(1) AuthController作成
コマンドラインで
cd sample
php artisan make:controller AuthController
xdebugの設定をしているとeclipseが実行していいですかというプロンプトを出すのでOKを押します
eclipseプロジェクトを右クリック→リフレッシュ
/sample/app/Http/Controllers/AuthController.phpが現れます
/sample/app/Http/Controllers/AuthController.phpを下記に修正します
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class AuthController extends Controller
{
public function __construct()
{
$this->middleware('auth:api', ['except' => ['login']]);
}
public function login()
{
$credentials = request(['email', 'password']);
if (! $token = auth('api')->attempt($credentials)) {
return response()->json(['error' => 'メールアドレス、またはパスワードが間違っています'], 401);
}
return $this->respondWithToken($token);
}
public function me()
{
return response()->json(auth('api')->user());
}
public function logout()
{
auth('api')->logout();
return response()->json(['message' => 'Successfully logged out']);
}
public function refresh()
{
return $this->respondWithToken(auth('api')->refresh());
}
protected function respondWithToken($token)
{
return response()->json([
'access_token' => $token,
'token_type' => 'bearer',
'expires_in' => auth('api')->factory()->getTTL() * 60
]);
}
}
jwt-authの公式ドキュメントとほとんど同じですが、違っている箇所があります。
auth()関数に引数'api'を渡しています
jwt-authの公式ドキュメントではauth.phpのdefaultsのguardをapiにしているので、auth()に引数を渡さなくてもjwtのguardが取れますが、今回はdefaultsのguardはwebのままにしますので、auth()関数に引数'api'を渡すようにします
また、コンストラクタでmiddlewareを指定しています。middlewareは/sample/routes/web.phpや/sample/routes/api.phpの中でRoute::getやRoute::postの戻り値に対して指定することもできますが、コンストラクタで指定することもできます。この場合$this->middleware('auth:api', ['except' => ['login']]);
なので、loginメソッドを除いて、メソッドにリクエストが来るとguard->apiの認証が必要になります
(2) SampleController.php修正
/sample/app/Http/Controllers/SampleController.php修正
api1メソッド、api2メソッド追加
public function api1()
{
return view('sample.api');
}
public function api2(Request $request)
{
$data = [
'a' => 'a_value',
'b' => 'b_value',
'c' => $request->input('c')
];
return $data;
}
(3) /sample/routes/api.php修正
下記を追記
Route::post('auth/login', 'AuthController@login');
Route::post('auth/logout', 'AuthController@logout');
Route::post('auth/refresh', 'AuthController@refresh');
Route::post('auth/me', 'AuthController@me');
Route::post('sample/api2', 'SampleController@api2')->middleware('auth:api');
/sample/routes/api.phpにルーティングを書いた場合、app/Providers/RouteServiceProvider.php#mapApiRoutesによって自動的に/apiがURLの先頭につきます
AuthControllerの各メソッドはAuthControllerのコンストラクタ内で認証の要、不要が設定されていますが、SampleControllerのapi2はここで認証が必要なようにmiddlewareを付けました
(4) /sample/routes/web.php修正
下記を追記
Route::get('sample/api1', 'SampleController@api1');
要ログインURLへ未認証ユーザーがアクセスした場合のエラーメッセージ修正
/sample/app/Http/Middleware/Authenticate.php修正
unauthenticatedメソッド追加
protected function unauthenticated($request, array $guards)
{
throw new AuthenticationException(
'ログインしてください', $guards, $this->redirectTo($request)
);
}
view作成
/sample/resources/views/sample/api.blade.php
<html>
<head>
<title>sample</title>
<script type="text/javascript">
function login(){
var form = document.getElementById("sampleForm1");
var reqData = {"email": null, "password": null};
reqData.email = form.email.value;
reqData.password = form.password.value;
var req = new XMLHttpRequest();
req.open(form.method, form.action);
req.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
req.responseType = 'json';
req.send(JSON.stringify(reqData));
req.onload = function () {
var json = req.response;
if (json['error']) {
alert("error:" + json['error']);
} else {
localStorage.setItem('access_token', json['access_token']);
alert('ログイン');
}
}
}
function ajax(){
var form = document.getElementById("sampleForm2");
var reqData = {"c": null};
reqData.c = form.c.value;
var req = new XMLHttpRequest();
req.open(form.method, form.action);
req.setRequestHeader('Authorization', 'Bearer ' + localStorage.getItem('access_token'));
req.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
req.setRequestHeader('Accept', 'application/json');
req.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
req.responseType = 'json';
req.send(JSON.stringify(reqData));
req.onload = function () {
var json = req.response;
if (json['message']) {
alert("message:" + json['message']);
} else {
alert("a:" + json['a'] + "\n" + "b:" + json['b']+ "\n" + "c:" + json['c']);
}
}
}
function logout(){
var form = document.getElementById("sampleForm3");
var req = new XMLHttpRequest();
req.open(form.method, form.action);
req.setRequestHeader('Authorization', 'Bearer ' + localStorage.getItem('access_token'));
req.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
req.setRequestHeader('Accept', 'application/json');
req.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
req.responseType = 'json';
req.send();
req.onload = function () {
var json = req.response;
alert("message:" + json['message']);
}
}
</script>
</head>
<body>
<form id="sampleForm1" action="{{ url('api/auth/login') }}" method="post" onsubmit="login(); return false;" style="border: #000000 solid 1px; padding: 10px;">
<div>email:<input type="text" name="email" ></div>
<div>password:<input type="password" name="password" ></div>
<input type="submit" value="ログイン">
</form>
<br>
<br>
<form id="sampleForm2" action="{{ url('api/sample/api2') }}" method="post" onsubmit="ajax(); return false;" style="border: #000000 solid 1px; padding: 10px;">
<input type="text" name="c" >
<input type="submit" value="要認証リクエスト">
</form>
<br>
<br>
<form id="sampleForm3" action="{{ url('api/auth/logout') }}" method="post" onsubmit="logout(); return false;" style="border: #000000 solid 1px; padding: 10px;">
<input type="submit" value="ログアウト">
</form>
</body>
</html>
動作確認
http://localhost/laravelSample/sample/api1
・要認証リクエストの左にあるテキストフィールドに何か入力し、要認証リクエストボタンをクリックします
ログインしてくださいとalertがでました
・メールアドレスとパスワードを入力してログインボタンをクリックします
ログインできました
・要認証リクエストの左にあるテキストフィールドに何か入力し、要認証リクエストボタンをクリックします
SampleController.php#api2のレスポンスが表示されました
・ログアウトボタンをクリックします
ログアウトしました