ホームページ > PHPフレームワーク > Laravel > Laravel を使用して JWT 認証を統合し、RestfulApi を開発する

Laravel を使用して JWT 認証を統合し、RestfulApi を開発する

Guanhui
リリース: 2020-05-09 10:43:45
転載
2625 人が閲覧しました

この記事では、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 ユーザー は次の機能を使用します

  • 登録して新しいアカウントを作成します

  • ログアカウントに移動します

  • ログアウトしてトークンを破棄し、アプリを終了します

  • #ログインしているユーザーの詳細を取得します

  • ユーザーが利用できる製品のリストを取得します

  • ID で特定の製品を検索します

  • ユーザーの製品に新しい製品を追加します製品リスト

  • 既存の製品詳細の編集

  • ユーザー リストから既存の製品を削除

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 [

    &#39;secret&#39; => env(&#39;JWT_SECRET&#39;),

    &#39;keys&#39; => [

        &#39;public&#39; => env(&#39;JWT_PUBLIC_KEY&#39;),

        &#39;private&#39; => env(&#39;JWT_PRIVATE_KEY&#39;),

        &#39;passphrase&#39; => env(&#39;JWT_PASSPHRASE&#39;),

    ],

    &#39;ttl&#39; => env(&#39;JWT_TTL&#39;, 60),

    &#39;refresh_ttl&#39; => env(&#39;JWT_REFRESH_TTL&#39;, 20160),

    &#39;algo&#39; => env(&#39;JWT_ALGO&#39;, &#39;HS256&#39;),

    &#39;required_claims&#39; => [

        &#39;iss&#39;,

        &#39;iat&#39;,

        &#39;exp&#39;,

        &#39;nbf&#39;,

        &#39;sub&#39;,

        &#39;jti&#39;,

    ],

    &#39;persistent_claims&#39; => [

        // &#39;foo&#39;,

        // &#39;bar&#39;,

    ],

    &#39;lock_subject&#39; => true,

    &#39;leeway&#39; => env(&#39;JWT_LEEWAY&#39;, 0),

    &#39;blacklist_enabled&#39; => env(&#39;JWT_BLACKLIST_ENABLED&#39;, true),

    &#39;blacklist_grace_period&#39; => env(&#39;JWT_BLACKLIST_GRACE_PERIOD&#39;, 0),

    &#39;decrypt_cookies&#39; => false,

    &#39;providers&#39; => [

        &#39;jwt&#39; => Tymon\JWTAuth\Providers\JWT\Lcobucci::class,

        &#39;auth&#39; => Tymon\JWTAuth\Providers\Auth\Illuminate::class,

        &#39;storage&#39; => Tymon\JWTAuth\Providers\Storage\Illuminate::class,

    ],

];

ログイン後にコピー

JWT キーの生成

JWT トークンは、暗号化されたキーを使用して発行されます。 Laravel 5.5 以降の場合、次のコマンドを実行してトークンを発行するためのキーを生成します。

1

php artisan jwt:secret

ログイン後にコピー
Laravel バージョンが 5.5 より前の場合は、次を実行します:

1

php artisan jwt:generate

ログイン後にコピー

このチュートリアルでは Laravel 5.6 を使用します。チュートリアルの次の手順は、5.5 と 5.6 でのみテストされています。 Laravel 5.4 以前では動作しない可能性があります。 Laravel の古いバージョンのドキュメントを読むことができます。

登録ミドルウェア

JWT 認証拡張パッケージには、それを使用できるようにするミドルウェアが付属しています。 auth.jwt ミドルウェアを app/Http/Kernel.php に登録します:

1

2

3

4

protected $routeMiddleware = [

    ....

    &#39;auth.jwt&#39; => \Tymon\JWTAuth\Http\Middleware\Authenticate::class,

];

ログイン後にコピー
このミドルウェアは、リクエストに添付されたトークンをチェックすることでユーザーの認証を検証します。ユーザーが認証されていない場合、このミドルウェアは UnauthorizedHttpException 例外をスローします。

ルーティングのセットアップ

始める前に、このチュートリアルで説明するすべてのポイントのルーティングをセットアップします。 Routes/api.php を開き、次のルートをファイルにコピーします。

1

2

3

4

5

6

7

8

9

10

11

Route::post(&#39;login&#39;, &#39;ApiController@login&#39;);

Route::post(&#39;register&#39;, &#39;ApiController@register&#39;);

Route::group([&#39;middleware&#39; => &#39;auth.jwt&#39;], function () {

    Route::get(&#39;logout&#39;, &#39;ApiController@logout&#39;);

    Route::get(&#39;user&#39;, &#39;ApiController@getAuthUser&#39;);

    Route::get(&#39;products&#39;, &#39;ProductController@index&#39;);

    Route::get(&#39;products/{id}&#39;, &#39;ProductController@show&#39;);

    Route::post(&#39;products&#39;, &#39;ProductController@store&#39;);

    Route::put(&#39;products/{id}&#39;, &#39;ProductController@update&#39;);

    Route::delete(&#39;products/{id}&#39;, &#39;ProductController@destroy&#39;);

});

ログイン後にコピー

ユーザー モデルの更新

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;

    /**

     * The attributes that are mass assignable.

     *

     * @var array

     */

    protected $fillable = [

        &#39;name&#39;, &#39;email&#39;, &#39;password&#39;,

    ];

    /**

     * The attributes that should be hidden for arrays.

     *

     * @var array

     */

    protected $hidden = [

        &#39;password&#39;, &#39;remember_token&#39;,

    ];

    /**

     * Get the identifier that will be stored in the subject claim of the JWT.

     *

     * @return mixed

     */

    public function getJWTIdentifier()

    {

        return $this->getKey();

    }

    /**

     * Return a key value array, containing any custom claims to be added to the JWT.

     *

     * @return array

     */

    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

{

    /**

     * 确定是否授权用户发出此请求

     *

     * @return bool

     */

    public function authorize()

    {

        return true;

    }

    /**

     * 获取应用于请求的验证规则

     *

     * @return array

     */

    public function rules()

    {

        return [

            &#39;name&#39; => &#39;required|string&#39;,

            &#39;email&#39; => &#39;required|email|unique:users&#39;,

            &#39;password&#39; => &#39;required|string|min:6|max:10&#39;

        ];

    }

}

ログイン後にコピー

运行以下命令创建一个新的 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([

            &#39;success&#39; => true,

            &#39;data&#39; => $user

        ], 200);

    }

    public function login(Request $request)

    {

        $input = $request->only(&#39;email&#39;, &#39;password&#39;);

        $jwt_token = null;

        if (!$jwt_token = JWTAuth::attempt($input)) {

            return response()->json([

                &#39;success&#39; => false,

                &#39;message&#39; => &#39;Invalid Email or Password&#39;,

            ], 401);

        }

        return response()->json([

            &#39;success&#39; => true,

            &#39;token&#39; => $jwt_token,

        ]);

    }

    public function logout(Request $request)

    {

        $this->validate($request, [

            &#39;token&#39; => &#39;required&#39;

        ]);

        try {

            JWTAuth::invalidate($request->token);

            return response()->json([

                &#39;success&#39; => true,

                &#39;message&#39; => &#39;User logged out successfully&#39;

            ]);

        } catch (JWTException $exception) {

            return response()->json([

                &#39;success&#39; => false,

                &#39;message&#39; => &#39;Sorry, the user cannot be logged out&#39;

            ], 500);

        }

    }

    public function getAuthUser(Request $request)

    {

        $this->validate($request, [

            &#39;token&#39; => &#39;required&#39;

        ]);

        $user = JWTAuth::authenticate($request->token);

        return response()->json([&#39;user&#39; => $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(&#39;products&#39;, function (Blueprint $table) {

        $table->increments(&#39;id&#39;);

        $table->integer(&#39;user_id&#39;);

        $table->string(&#39;name&#39;);

        $table->integer(&#39;price&#39;);

        $table->integer(&#39;quantity&#39;);

        $table->timestamps();

        $table->foreign(&#39;user_id&#39;)

            ->references(&#39;id&#39;)

            ->on(&#39;users&#39;)

            ->onDelete(&#39;cascade&#39;);

    });

}

ログイン後にコピー

向 Product 模型中添加 fillable 属性。在 app 目录下打开 Product.php 文件并添加属性。

1

2

3

protected $fillable = [

    &#39;name&#39;, &#39;price&#39;, &#39;quantity&#39;

];

ログイン後にコピー

现在在 .env 文件中设置数据库凭证,并通过运行以下命令迁移数据库。

1

php artisan migrate

ログイン後にコピー

现在,我们必须在 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([&#39;name&#39;, &#39;price&#39;, &#39;quantity&#39;])

        ->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([

            &#39;success&#39; => false,

            &#39;message&#39; => &#39;Sorry, product with id &#39; . $id . &#39; cannot be found&#39;

        ], 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, [

        &#39;name&#39; => &#39;required&#39;,

        &#39;price&#39; => &#39;required|integer&#39;,

        &#39;quantity&#39; => &#39;required|integer&#39;

    ]);

    $product = new Product();

    $product->name = $request->name;

    $product->price = $request->price;

    $product->quantity = $request->quantity;

    if ($this->user->products()->save($product))

        return response()->json([

            &#39;success&#39; => true,

            &#39;product&#39; => $product

        ]);

    else

        return response()->json([

            &#39;success&#39; => false,

            &#39;message&#39; => &#39;Sorry, product could not be added&#39;

        ], 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([

            &#39;success&#39; => false,

            &#39;message&#39; => &#39;Sorry, product with id &#39; . $id . &#39; cannot be found&#39;

        ], 400);

    }

    $updated = $product->fill($request->all())

        ->save();

    if ($updated) {

        return response()->json([

            &#39;success&#39; => true

        ]);

    } else {

        return response()->json([

            &#39;success&#39; => false,

            &#39;message&#39; => &#39;Sorry, product could not be updated&#39;

        ], 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([

            &#39;success&#39; => false,

            &#39;message&#39; => &#39;Sorry, product with id &#39; . $id . &#39; cannot be found&#39;

        ], 400);

    }

    if ($product->delete()) {

        return response()->json([

            &#39;success&#39; => true

        ]);

    } else {

        return response()->json([

            &#39;success&#39; => false,

            &#39;message&#39; => &#39;Product could not be deleted&#39;

        ], 500);

    }

}

ログイン後にコピー

在 destroy 方法中,我们根据 ID 获取产品,如果产品不存在,则返回 400 响应。然后我们删除产品后并根据删除操作的成功状态返回适当的响应。

控制器代码现在已经完成,完整的控制器代码在这。

测试

我们首先来测试身份认证。我们将使用 serve 命令在开发机上启动 Web 服务,你也可以使用虚拟主机代替。运行以下命令启动 Web 服务。

1

php artisan serve

ログイン後にコピー

它将监听 localhost:8000

为了测试 restful API's,我们使用 Postman。填写好请求体之后,我们请求一下 register 路由。

Laravel を使用して JWT 認証を統合し、RestfulApi を開発する

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

Laravel を使用して JWT 認証を統合し、RestfulApi を開発する

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

Laravel を使用して JWT 認証を統合し、RestfulApi を開発する

#ユーザー詳細の取得

Laravel を使用して JWT 認証を統合し、RestfulApi を開発する

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

Laravel を使用して JWT 認証を統合し、RestfulApi を開発する

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

Laravel を使用して JWT 認証を統合し、RestfulApi を開発する

他のルートをテストすると、すべて正常に動作します。

推奨チュートリアル: 「

Laravel チュートリアル

以上がLaravel を使用して JWT 認証を統合し、RestfulApi を開発するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート