この記事では、JWT 認証を使用して Laravel で RESTful API を構築する方法を学びます。 JWT は JSON Web トークンの略です。また、API を使用して、ユーザー製品用の完全に機能する CRUD アプリケーションを作成します。
API は、クロスプラットフォーム アプリケーションを使用する場合に非常に良い選択肢です。 Web サイトに加えて、製品には Android および iOS アプリも含まれている場合があります。この場合、バックエンド コードを変更せずにさまざまなフロントエンドを作成できるため、API も同様に優れています。 API を使用する場合、いくつかのパラメーターを指定して GET、POST、またはその他のタイプのリクエストを実行するだけで、サーバーは JSON (JavaScript Object Notation) 形式でデータを返し、クライアント アプリケーションによって処理されます。
手順
まずは、アプリケーションの詳細と機能を書き留めましょう。 JWT認証を使用したlaravelのRestful APIを使用して、基本的なユーザー製品リストを構築します。
A ユーザー は次の機能を使用します
A
ユーザー 必須
A
製品 必須
- ##名前
-
##価格
##数量
新しいアイテムの作成
次のコマンドを実行すると、新しい Laravel プロジェクトを開始して作成できます。 composer create-project --prefer-dist laravel/laravel jwt
これにより、jwt という名前のディレクトリに新しい Laravel プロジェクトが作成されます。
JWT 拡張パッケージの構成
Laravel で JWT を使用できるようにするために、tymondesigns/jwt-auth 拡張パッケージを使用します。
tymon/jwt-auth 拡張パッケージをインストールします
この拡張パッケージをこの Laravel アプリケーションにインストールしましょう。 Laravel 5.5 以降を使用している場合は、次のコマンドを実行して JWT パッケージの開発-開発バージョンを取得してください:
1 | composer require tymon/jwt-auth:dev-develop --prefer-source
|
ログイン後にコピー
Laravel 5.4 以前を使用している場合は、次のコマンドを実行します:
1 | composer require tymon/jwt-auth
|
ログイン後にコピー
Laravel バージョン 5.5 より前のアプリケーションの場合は、config/app.php ファイルでサービスプロバイダーとエイリアスを設定する必要もあります。
1 2 3 4 5 6 7 8 9 10 11 | 'providers' => [
....
Tymon\JWTAuth\Providers\JWTAuthServiceProvider:: class ,
....
],
'aliases' => [
....
'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth:: class ,
'JWTFactory' => 'Tymon\JWTAuth\Facades\JWTFactory',
....
],
|
ログイン後にコピー
Laravel のバージョンが 5.5 以降の場合、Laravel は「パッケージの自動検出」を実行します。
設定ファイルの公開
Laravel バージョン 5.5 以降の場合は、次のコマンドを使用して設定ファイルを公開してください:
1 | php artisan vendor:publish --provider= "Tymon\JWTAuth\Providers\LaravelServiceProvider"
|
ログイン後にコピー
Laravel の以前のバージョンの場合は、次のコマンドを実行する必要があります:
1 | php artisan vendor:publish --provider= "Tymon\JWTAuth\Providers\JWTAuthServiceProvider"
|
ログイン後にコピー
上記のコマンドは config/jwt.php 構成ファイルを生成します。コメントがなければ、構成ファイルは次のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | <?php
return [
'secret' => env('JWT_SECRET'),
'keys' => [
' public ' => env('JWT_PUBLIC_KEY'),
' private ' => env('JWT_PRIVATE_KEY'),
'passphrase' => env('JWT_PASSPHRASE'),
],
'ttl' => env('JWT_TTL', 60),
'refresh_ttl' => env('JWT_REFRESH_TTL', 20160),
'algo' => env('JWT_ALGO', 'HS256'),
'required_claims' => [
'iss',
'iat',
' exp ',
'nbf',
'sub',
'jti',
],
'persistent_claims' => [
],
'lock_subject' => true,
'leeway' => env('JWT_LEEWAY', 0),
'blacklist_enabled' => env('JWT_BLACKLIST_ENABLED', true),
'blacklist_grace_period' => env('JWT_BLACKLIST_GRACE_PERIOD', 0),
'decrypt_cookies' => false,
'providers' => [
'jwt' => Tymon\JWTAuth\Providers\JWT\Lcobucci:: class ,
'auth' => Tymon\JWTAuth\Providers\Auth\Illuminate:: class ,
'storage' => Tymon\JWTAuth\Providers\Storage\Illuminate:: class ,
],
];
|
ログイン後にコピー
JWT キーの生成
JWT トークンは、暗号化されたキーを使用して発行されます。 Laravel 5.5 以降の場合、次のコマンドを実行してトークンを発行するためのキーを生成します。
Laravel バージョンが 5.5 より前の場合は、次を実行します:
このチュートリアルでは Laravel 5.6 を使用します。チュートリアルの次の手順は、5.5 と 5.6 でのみテストされています。 Laravel 5.4 以前では動作しない可能性があります。 Laravel の古いバージョンのドキュメントを読むことができます。
登録ミドルウェア
JWT 認証拡張パッケージには、それを使用できるようにするミドルウェアが付属しています。 auth.jwt ミドルウェアを app/Http/Kernel.php に登録します:
1 2 3 4 | protected $routeMiddleware = [
....
'auth.jwt' => \Tymon\JWTAuth\Http\Middleware\Authenticate:: class ,
];
|
ログイン後にコピー
このミドルウェアは、リクエストに添付されたトークンをチェックすることでユーザーの認証を検証します。ユーザーが認証されていない場合、このミドルウェアは UnauthorizedHttpException 例外をスローします。
ルーティングのセットアップ
始める前に、このチュートリアルで説明するすべてのポイントのルーティングをセットアップします。 Routes/api.php を開き、次のルートをファイルにコピーします。
1 2 3 4 5 6 7 8 9 10 11 | Route::post('login', 'ApiController@login');
Route::post('register', 'ApiController@register');
Route::group(['middleware' => 'auth.jwt'], function () {
Route::get('logout', 'ApiController@logout');
Route::get('user', 'ApiController@getAuthUser');
Route::get('products', 'ProductController@index');
Route::get('products/{id}', 'ProductController@show');
Route::post('products', 'ProductController@store');
Route::put('products/{id}', 'ProductController@update');
Route:: delete ('products/{id}', 'ProductController@destroy');
});
|
ログイン後にコピー
ユーザー モデルの更新
JWT は、ユーザー モデルに Tymon\JWTAuth\Contracts\JWTSubject インターフェイスを実装する必要があります。このインターフェイスは、getJWTIdentifier と getJWTCustomClaims の 2 つのメソッドを実装する必要があります。 app/User.php を次の内容で更新します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | <?php
namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Tymon\JWTAuth\Contracts\JWTSubject;
class User extends Authenticatable implements JWTSubject
{
use Notifiable;
protected $fillable = [
'name', 'email', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
public function getJWTIdentifier()
{
return $this ->getKey();
}
public function getJWTCustomClaims()
{
return [];
}
}
|
ログイン後にコピー
JWT 認証ロジック
JWT 認証を使用して、laravel で Restful API のロジックを書いてみましょう。
用户注册时需要姓名,邮箱和密码。那么,让我们创建一个表单请求来验证数据。通过运行以下命令创建名为 RegisterAuthRequest 的表单请求:
1 | php artisan make:request RegisterAuthRequest
|
ログイン後にコピー
它将在 app/Http/Requests 目录下创建 RegisterAuthRequest.php 文件。将下面的代码黏贴至该文件中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class RegisterAuthRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'name' => 'required|string',
'email' => 'required|email|unique:users',
'password' => 'required|string|min:6|max:10'
];
}
}
|
ログイン後にコピー
运行以下命令创建一个新的 ApiController :
1 | php artisan make:controller ApiController
|
ログイン後にコピー
这将会在 app/Http/Controllers 目录下创建 ApiController.php 文件。将下面的代码黏贴至该文件中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | <?php
namespace App\Http\Controllers;
use App\Http\Requests\RegisterAuthRequest;
use App\User;
use Illuminate\Http\Request;
use JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;
class ApiController extends Controller
{
public $loginAfterSignUp = true;
public function register(RegisterAuthRequest $request )
{
$user = new User();
$user ->name = $request ->name;
$user ->email = $request ->email;
$user ->password = bcrypt( $request ->password);
$user ->save();
if ( $this ->loginAfterSignUp) {
return $this ->login( $request );
}
return response()->json([
'success' => true,
'data' => $user
], 200);
}
public function login(Request $request )
{
$input = $request ->only('email', 'password');
$jwt_token = null;
if (! $jwt_token = JWTAuth::attempt( $input )) {
return response()->json([
'success' => false,
'message' => 'Invalid Email or Password',
], 401);
}
return response()->json([
'success' => true,
'token' => $jwt_token ,
]);
}
public function logout(Request $request )
{
$this ->validate( $request , [
'token' => 'required'
]);
try {
JWTAuth::invalidate( $request ->token);
return response()->json([
'success' => true,
'message' => 'User logged out successfully'
]);
} catch (JWTException $exception ) {
return response()->json([
'success' => false,
'message' => 'Sorry, the user cannot be logged out'
], 500);
}
}
public function getAuthUser(Request $request )
{
$this ->validate( $request , [
'token' => 'required'
]);
$user = JWTAuth::authenticate( $request ->token);
return response()->json(['user' => $user ]);
}
}
|
ログイン後にコピー
让我解释下上面的代码发生了什么。
在 register 方法中,我们接收了 RegisterAuthRequest 。使用请求中的数据创建用户。如果 loginAfterSignUp 属性为 true ,则注册后通过调用 login 方法为用户登录。否则,成功的响应则将伴随用户数据一起返回。
在 login 方法中,我们得到了请求的子集,其中只包含电子邮件和密码。以输入的值作为参数调用 JWTAuth::attempt() ,响应保存在一个变量中。如果从 attempt 方法中返回 false ,则返回一个失败响应。否则,将返回一个成功的响应。
在 logout 方法中,验证请求是否包含令牌验证。通过调用 invalidate 方法使令牌无效,并返回一个成功的响应。如果捕获到 JWTException 异常,则返回一个失败的响应。
在 getAuthUser 方法中,验证请求是否包含令牌字段。然后调用 authenticate 方法,该方法返回经过身份验证的用户。最后,返回带有用户的响应。
身份验证部分现在已经完成。
构建产品部分
要创建产品部分,我们需要 Product 模型,控制器和迁移文件。运行以下命令来创建 Product 模型,控制器和迁移文件。
1 | php artisan make:model Product -mc
|
ログイン後にコピー
它会在 database/migrations 目录下创建一个新的数据库迁移文件 create_products_table.php,更改 up 方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public function up()
{
Schema::create('products', function (Blueprint $table ) {
$table ->increments('id');
$table ->integer('user_id');
$table ->string('name');
$table ->integer('price');
$table ->integer('quantity');
$table ->timestamps();
$table ->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade');
});
}
|
ログイン後にコピー
向 Product 模型中添加 fillable 属性。在 app 目录下打开 Product.php 文件并添加属性。
1 2 3 | protected $fillable = [
'name', 'price', 'quantity'
];
|
ログイン後にコピー
现在在 .env 文件中设置数据库凭证,并通过运行以下命令迁移数据库。
现在,我们必须在 User 模型中添加一个关系来检索相关产品。在 app/User.php 中添加以下方法。
1 2 3 4 | public function products()
{
return $this ->hasMany(Product:: class );
}
|
ログイン後にコピー
在 app/Http/Controllers 目录下打开 ProductController.php 文件。在文件开头添加 use 指令覆盖上一个。
1 2 3 | use App\Product;
use Illuminate\Http\Request;
use JWTAuth;
|
ログイン後にコピー
现在我们将实现五个方法。
index, 为经过身份认证的用户获取所有产品列表
show, 根据 ID 获取特定的产品
store, 将新产品存储到产品列表中
update, 根据 ID 更新产品详情
destroy, 根据 ID 从列表中删除产品
添加一个构造函数来获取经过身份认证的用户,并将其保存在 user 属性中。
1 2 3 4 5 | protected $user ;
public function __construct()
{
$this ->user = JWTAuth::parseToken()->authenticate();
}
|
ログイン後にコピー
parseToken 将解析来自请求的令牌, authenticate 通过令牌对用户进行身份验证。
让我们添加 index 方法。
1 2 3 4 5 6 7 | public function index()
{
return $this ->user
->products()
->get(['name', 'price', 'quantity'])
->toArray();
}
|
ログイン後にコピー
上面的代码非常简单,我们只是使用 Eloquent 的方法获取所有的产品,然后将结果组成一个数组。最后,我们返回这个数组。Laravel 将自动将其转换为 JSON ,并创建一个为 200 成功的响应码。
继续实现 show 方法。
1 2 3 4 5 6 7 8 9 10 11 | public function show( $id )
{
$product = $this ->user->products()->find( $id );
if (! $product ) {
return response()->json([
'success' => false,
'message' => 'Sorry, product with id ' . $id . ' cannot be found'
], 400);
}
return $product ;
}
|
ログイン後にコピー
这个也非常容易理解。我们只需要根据 ID 找到该产品。如果产品不存在,则返回 400 故障响应。否则,将返回产品数组。
接下来是 store 方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | public function store(Request $request )
{
$this ->validate( $request , [
'name' => 'required',
'price' => 'required|integer',
'quantity' => 'required|integer'
]);
$product = new Product();
$product ->name = $request ->name;
$product ->price = $request ->price;
$product ->quantity = $request ->quantity;
if ( $this ->user->products()->save( $product ))
return response()->json([
'success' => true,
'product' => $product
]);
else
return response()->json([
'success' => false,
'message' => 'Sorry, product could not be added'
], 500);
}
|
ログイン後にコピー
在 store 方法中,验证请求中是否包含名称,价格和数量。然后,使用请求中的数据去创建一个新的产品模型。如果,产品成功的写入数据库,会返回成功响应,否则返回自定义的 500 失败响应。
实现 update 方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | public function update(Request $request , $id )
{
$product = $this ->user->products()->find( $id );
if (! $product ) {
return response()->json([
'success' => false,
'message' => 'Sorry, product with id ' . $id . ' cannot be found'
], 400);
}
$updated = $product ->fill( $request ->all())
->save();
if ( $updated ) {
return response()->json([
'success' => true
]);
} else {
return response()->json([
'success' => false,
'message' => 'Sorry, product could not be updated'
], 500);
}
}
|
ログイン後にコピー
在 update 方法中,我们通过 id 取得产品。如果产品不存在,返回一个 400 响应。然后,我们把请求中的数据使用 fill 方法填充到产品详情。更新产品模型并保存到数据库,如果记录成功更新,返回一个 200 成功响应,否则返回 500 内部服务器错误响应给客户端。
现在,让我们实现 destroy 方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | public function destroy( $id )
{
$product = $this ->user->products()->find( $id );
if (! $product ) {
return response()->json([
'success' => false,
'message' => 'Sorry, product with id ' . $id . ' cannot be found'
], 400);
}
if ( $product -> delete ()) {
return response()->json([
'success' => true
]);
} else {
return response()->json([
'success' => false,
'message' => 'Product could not be deleted'
], 500);
}
}
|
ログイン後にコピー
在 destroy 方法中,我们根据 ID 获取产品,如果产品不存在,则返回 400 响应。然后我们删除产品后并根据删除操作的成功状态返回适当的响应。
控制器代码现在已经完成,完整的控制器代码在这。
测试
我们首先来测试身份认证。我们将使用 serve 命令在开发机上启动 Web 服务,你也可以使用虚拟主机代替。运行以下命令启动 Web 服务。
它将监听 localhost:8000
为了测试 restful API's,我们使用 Postman。填写好请求体之后,我们请求一下 register 路由。

リクエストを送信すると、トークンを取得します。

ユーザーは登録され、認証されました。ログイン ルートを検出するために別のリクエストを送信すると、200 とトークンが返されます。

#ユーザー詳細の取得

ID 認証のテストが完了しました。次に、製品部分をテストし、最初に製品を作成します。

次に、index メソッドをリクエストして製品を取得します。

他のルートをテストすると、すべて正常に動作します。
推奨チュートリアル: 「
Laravel チュートリアル 」
以上がLaravel を使用して JWT 認証を統合し、RestfulApi を開発するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。