Heim  >  Artikel  >  PHP-Framework  >  Verwendung von Laravel zur Integration der JWT-Authentifizierung zur Entwicklung von RestfulApi

Verwendung von Laravel zur Integration der JWT-Authentifizierung zur Entwicklung von RestfulApi

Guanhui
Guanhuinach vorne
2020-05-09 10:43:452354Durchsuche

In diesem Artikel erfahren Sie, wie Sie mithilfe der JWT-Authentifizierung eine erholsame API in Laravel erstellen. JWT steht für JSON Web Tokens. Wir werden die API auch verwenden, um eine voll funktionsfähige CRUD-Anwendung für das Benutzerprodukt zu erstellen.

API ist eine sehr gute Wahl, wenn Sie plattformübergreifende Anwendungen verwenden. Zusätzlich zu einer Website verfügt Ihr Produkt möglicherweise auch über Android- und iOS-Apps. In diesem Fall ist die API ebenso großartig, da Sie verschiedene Frontends schreiben können, ohne den Backend-Code zu ändern. Wenn Sie die API verwenden, drücken Sie einfach GET , POST oder eine andere Art von Anfrage mit einigen Parametern, und der Server gibt einige Daten im JSON-Format (JavaScript Object Notation) zurück, die von der Clientanwendung verarbeitet werden.

Anleitung

Beginnen wir damit, die Details und Funktionen unserer App aufzuschreiben. Wir werden mithilfe der Restful-API in Laravel und der JWT-Authentifizierung eine grundlegende Benutzerproduktliste erstellen.

Ein Benutzer wird die folgenden Funktionen nutzen

  • Registrieren und ein neues Konto erstellen

  • Loggen in Gehen Sie zu ihrem Konto

  • melden Sie sich ab, verwerfen Sie das Token und verlassen Sie die App

  • Angemeldete Benutzerdaten abrufen

  • Rufen Sie eine Liste der für den Benutzer verfügbaren Produkte ab

  • Suchen Sie ein bestimmtes Produkt anhand der ID

  • Fügen Sie ein neues Produkt hinzu die Produktliste des Benutzers

  • Vorhandene Produktdetails bearbeiten

  • Vorhandenes Produkt aus der Benutzerliste entfernen

Ein Benutzer Erforderlich

  • Name

  • E-Mail-Adresse

  • Passwort

Ein Produkt Erforderlich

  • Name

  • Preis

  • Menge

Neuen Artikel erstellen

Durch Ausführen des Mit dem folgenden Befehl können wir ein neues Laravel-Projekt starten und erstellen.

composer create-project --prefer-dist laravel/laravel jwt

Dadurch wird ein neues Laravel-Projekt in einem Verzeichnis namens jwt erstellt.

Konfigurieren des JWT-Erweiterungspakets

Wir werden das Erweiterungspaket tymondesigns/jwt-auth verwenden, um die Verwendung von JWT in Laravel zu ermöglichen.

Installieren Sie das Tymon/jwt-auth-Erweiterungspaket

Lassen Sie uns dieses Erweiterungspaket in dieser Laravel-Anwendung installieren. Wenn Sie Laravel 5.5 oder höher verwenden, führen Sie bitte den folgenden Befehl aus, um die Dev-Develop-Version des JWT-Pakets zu erhalten:

composer require tymon/jwt-auth:dev-develop --prefer-source

Wenn Sie Laravel 5.4 oder höher verwenden, führen Sie den folgenden Befehl aus:

composer require tymon/jwt-auth

Für Anwendungen mit Laravel-Versionen unter 5.5 müssen Sie außerdem den Dienstanbieter und den Alias ​​in der Datei config/app.php festlegen.

'providers' => [
    ....
    Tymon\JWTAuth\Providers\JWTAuthServiceProvider::class,
    ....
],
'aliases' => [
    ....
    'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class,
    'JWTFactory' => 'Tymon\JWTAuth\Facades\JWTFactory',
    ....
],

Wenn Ihre Laravel-Version 5.5 oder höher ist, führt Laravel eine „automatische Paketerkennung“ durch.

Konfigurationsdatei veröffentlichen

Für Laravel Version 5.5 oder höher verwenden Sie bitte den folgenden Befehl, um die Konfigurationsdatei zu veröffentlichen:

php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"

Für frühere Versionen von Laravel sollten Sie den folgenden Befehl ausführen:

php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\JWTAuthServiceProvider"

Der obige Befehl generiert die Konfigurationsdatei config/jwt.php. Ohne die Kommentare würde die Konfigurationsdatei so aussehen:

<?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,
    ],
];

Generate JWT Key

JWT-Tokens werden mit einem verschlüsselten Schlüssel ausgegeben. Führen Sie für Laravel 5.5 oder höher den folgenden Befehl aus, um einen Schlüssel für die Ausgabe von Token zu generieren.

php artisan jwt:secret

Laravel-Versionen unter 5.5 laufen:

php artisan jwt:generate

Dieses Tutorial verwendet Laravel 5.6. Die nächsten Schritte im Tutorial wurden nur in 5.5 und 5.6 getestet. Funktioniert möglicherweise nicht mit Laravel 5.4 oder niedriger. Sie können die Dokumentation für ältere Versionen von Laravel lesen.

Registrierungs-Middleware

Die JWT-Authentifizierungserweiterung wird mit Middleware geliefert, die uns ihre Verwendung ermöglicht. Registrieren Sie die Middleware auth.jwt in app/Http/Kernel.php:

protected $routeMiddleware = [
    ....
    &#39;auth.jwt&#39; => \Tymon\JWTAuth\Http\Middleware\Authenticate::class,
];

Diese Middleware überprüft die Authentifizierung des Benutzers, indem sie das an die Anfrage angehängte Token überprüft. Wenn der Benutzer nicht authentifiziert ist, löst diese Middleware eine UnauthorizedHttpException-Ausnahme aus.

Routing einrichten

Bevor wir beginnen, richten wir das Routing für alle in diesem Tutorial besprochenen Punkte ein. Öffnen Sie „routes/api.php“ und kopieren Sie die folgenden Routen in Ihre Datei.

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;);
});

Benutzermodell aktualisieren

JWT muss die TymonJWTAuthContractsJWTSubject-Schnittstelle im Benutzermodell implementieren. Diese Schnittstelle muss zwei Methoden getJWTIdentifier und getJWTCustomClaims implementieren. Aktualisieren Sie app/User.php mit dem folgenden Inhalt.

<?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-Authentifizierungslogik

Lassen Sie uns die Logik der Restful API in Laravel unter Verwendung der JWT-Authentifizierung schreiben.

用户注册时需要姓名,邮箱和密码。那么,让我们创建一个表单请求来验证数据。通过运行以下命令创建名为 RegisterAuthRequest 的表单请求:

php artisan make:request RegisterAuthRequest

它将在 app/Http/Requests 目录下创建 RegisterAuthRequest.php 文件。将下面的代码黏贴至该文件中。

<?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 :

php artisan make:controller ApiController

这将会在 app/Http/Controllers 目录下创建 ApiController.php 文件。将下面的代码黏贴至该文件中。

<?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 模型,控制器和迁移文件。

php artisan make:model Product -mc

它会在 database/migrations 目录下创建一个新的数据库迁移文件 create_products_table.php,更改 up 方法。

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 文件并添加属性。

protected $fillable = [
    &#39;name&#39;, &#39;price&#39;, &#39;quantity&#39;
];

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

php artisan migrate

现在,我们必须在 User 模型中添加一个关系来检索相关产品。在 app/User.php 中添加以下方法。

public function products()
{
    return $this->hasMany(Product::class);
}

在 app/Http/Controllers 目录下打开 ProductController.php 文件。在文件开头添加 use 指令覆盖上一个。

use App\Product;
use Illuminate\Http\Request;
use JWTAuth;

现在我们将实现五个方法。

index, 为经过身份认证的用户获取所有产品列表

show, 根据 ID 获取特定的产品

store, 将新产品存储到产品列表中

update, 根据 ID 更新产品详情

destroy, 根据 ID 从列表中删除产品

添加一个构造函数来获取经过身份认证的用户,并将其保存在 user 属性中。

protected $user;
public function __construct()
{
    $this->user = JWTAuth::parseToken()->authenticate();
}

parseToken 将解析来自请求的令牌, authenticate 通过令牌对用户进行身份验证。

让我们添加 index 方法。

public function index()
{
    return $this->user
        ->products()
        ->get([&#39;name&#39;, &#39;price&#39;, &#39;quantity&#39;])
        ->toArray();
}

上面的代码非常简单,我们只是使用 Eloquent 的方法获取所有的产品,然后将结果组成一个数组。最后,我们返回这个数组。Laravel 将自动将其转换为 JSON ,并创建一个为 200 成功的响应码。

继续实现 show 方法。

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 方法

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 方法

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 方法。

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 服务。

php artisan serve

它将监听 localhost:8000

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

Verwendung von Laravel zur Integration der JWT-Authentifizierung zur Entwicklung von RestfulApi

Senden Sie eine Anfrage und Sie erhalten einen Token.

Verwendung von Laravel zur Integration der JWT-Authentifizierung zur Entwicklung von RestfulApi

Unser Benutzer ist nun registriert und authentifiziert. Wir können eine weitere Anfrage senden, um die Anmelderoute zu ermitteln, die eine 200 und ein Token zurückgibt.

Verwendung von Laravel zur Integration der JWT-Authentifizierung zur Entwicklung von RestfulApi

Benutzerdetails abrufen

Verwendung von Laravel zur Integration der JWT-Authentifizierung zur Entwicklung von RestfulApi

Test der Identitätsauthentifizierung abgeschlossen. Testen Sie als Nächstes den Produktteil und erstellen Sie zunächst ein Produkt.

Verwendung von Laravel zur Integration der JWT-Authentifizierung zur Entwicklung von RestfulApi

Jetzt erhalten Sie das Produkt, indem Sie die Indexmethode anfordern.

Verwendung von Laravel zur Integration der JWT-Authentifizierung zur Entwicklung von RestfulApi

Sie können andere Routen testen und sie werden alle gut funktionieren.

Empfohlenes Tutorial: „Laravel Tutorial

Das obige ist der detaillierte Inhalt vonVerwendung von Laravel zur Integration der JWT-Authentifizierung zur Entwicklung von RestfulApi. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:learnku.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen