使用 Laravel Passport 為你的 REST API 增加使用者認證功能

Summer__發表於2019-05-07

Laravel

在本教程中,我們將瞭解如何在 Laravel 應用中使用 laravel passport 認證。 我們還將使用 Laravel Passport 認證 構建一個簡單的產品 (建立, 查詢, 更新和刪除 )。

Laravel 已經提供了傳統的登入表單身份驗證,但是如果你想使用 APIs 呢?APIs 使用令牌來驗證使用者,因為它們不使用會話。當使用者通過 API 登入時,會生成令牌並將其傳送給使用者,該使用者可用於身份驗證。Laravel 提供 Passport ,可以毫無困難地使用 API 認證。

讓我們看看如何在 Laravel 應用程式中設定和配置用於 API 認證和 RESTful APIs 的 Laravel Passport 。

建立一個新的應用

我們新建一個Laravel 應用。 執行下面的命令就可以建立一個全新的laravel應用。

composer create-project --prefer-dist laravel/laravel passport
複製程式碼

安裝Passport擴充套件

我們使用composer安裝Passport擴充套件。 執行下面的命令來安裝這個擴充套件。

composer require laravel/passport
複製程式碼

Laravel配置Passport

Laravel Passport 擴充套件需要做一些配置。

服務提供者

我們使用的Laravel 5.6最新版本,它可以使用包發現並自動註冊服務。如果你使用 laravel 5.4 或者 更低版本,你需要在 config/app.php 檔案中為Passport註冊服務。就這樣,在這個檔案中的providers陣列中新增註冊服務。

'providers' => [
    ....
    Laravel\Passport\PassportServiceProvider::class,
]
複製程式碼

遷移和安裝

在**.env ** 檔案中設定資料庫憑據。 Laravel Passport 提供了需要在我們的資料庫中的護照表的遷移檔案。 Passport遷移用於儲存令牌和客戶端資訊。 執行migration 命令以將架構遷移到資料庫。

php artisan migrate
複製程式碼

接下來,需要使用以下命令安裝 Passport。 它將生成生成祕密訪問令牌所需的加密金鑰。

php artisan passport:install
複製程式碼

Passport 配置

在此步驟中,我們需要在 Laravel 應用程式中進行更改以完成 Passport 配置。

app/User.php

在你的  User model 中新增 Laravel\Passport\HasApiTokens trait 。它將提供一些輔助方法。

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Laravel\Passport\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, Notifiable;

    /**
     * 這是可被賦值屬性集合
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * 這是應該被隱藏的屬性集合
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];
}
複製程式碼

AuthServiceProvider

AuthServiceProvider 的引導方法中新增 Passport :: routes() 方法。 它將生成必要的路由。 這是 app/Providers/AuthServiceProvider.php 在更改後的樣子。

<?php

namespace App\Providers;

use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Laravel\Passport\Passport;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [
        'App\Model' => 'App\Policies\ModelPolicy',
    ];

    /**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();

        Passport::routes();
    }
}
複製程式碼

config/auth.php

在 config/auth.php 檔案中,將驅動程式設定為 passport。

return [
    ....

    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver' => 'passport',
            'provider' => 'users',
        ],
    ],

    ....
]
複製程式碼

建立路由

讓我們建立 API 路由,在 routes/api.php 新增路由。

Route::post('login', 'PassportController@login');
Route::post('register', 'PassportController@register');

Route::middleware('auth:api')->group(function () {
    Route::get('user', 'PassportController@details');

    Route::resource('products', 'ProductController');
});
複製程式碼

建立認證控制器

讓我們設定身份驗證邏輯。通過執行以下命令建立 Passport 控制器。

php artisan make:controller PassportController
複製程式碼

將以下程式碼複製到 app/Http/Controllers/PassportController.php

<?php

namespace App\Http\Controllers;

use App\User;
use Illuminate\Http\Request;

class PassportController extends Controller
{
    /**
     * Handles Registration Request
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function register(Request $request)
    {
        $this->validate($request, [
            'name' => 'required|min:3',
            'email' => 'required|email|unique:users',
            'password' => 'required|min:6',
        ]);

        $user = User::create([
            'name' => $request->name,
            'email' => $request->email,
            'password' => bcrypt($request->password)
        ]);

        $token = $user->createToken('TutsForWeb')->accessToken;

        return response()->json(['token' => $token], 200);
    }

    /**
     * Handles Login Request
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function login(Request $request)
    {
        $credentials = [
            'email' => $request->email,
            'password' => $request->password
        ];

        if (auth()->attempt($credentials)) {
            $token = auth()->user()->createToken('TutsForWeb')->accessToken;
            return response()->json(['token' => $token], 200);
        } else {
            return response()->json(['error' => 'UnAuthorised'], 401);
        }
    }

    /**
     * Returns Authenticated User Details
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function details()
    {
        return response()->json(['user' => auth()->user()], 200);
    }
}
複製程式碼

讓我來解釋一下上面的程式碼

在 register 的方法中,我們驗證請求資料然後建立使用者。我們使用  createToken 方法建立 token,並將名稱作為引數傳遞。最後,我們在 JSON 響應中返回 token。

在  login 方法中,我們嘗試使用請求引數進行身份驗證。然後,根據嘗試的成功或失敗返回適當的響應。

在 details 方法中我們只返回使用者模型。

建立產品 CRUD

讓我們建立一個產品的 CRUD。執行以下命令生成產品模型、遷移檔案、和控制器。

php artisan make:model Product -mc
複製程式碼

它將建立一個新的資料庫遷移檔案 create_products_table.php 在 database/migrations 資料夾. 將 up 方法更新成以下程式碼。

public function up()
{
    Schema::create('products', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('user_id');
        $table->string('name');
        $table->integer('price');
        $table->timestamps();

        $table->foreign('user_id')
            ->references('id')
            ->on('users');
    });
}
複製程式碼

現在, 新增 fillable 屬性到 Product 模型. 開啟 app 資料夾下的 Product.php 檔案.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    protected $fillable = [
        'name', 'price'
    ];
}
複製程式碼

現在我們執行資料遷移。

php artisan migrate
複製程式碼

現在,讓我們在 app/User.php 檔案中新增關聯關係方法。

public function products()
{
    return $this->hasMany(Product::class);
}
複製程式碼

開啟 app/Http/Controllers 資料夾中的 ProductController.php 檔案。複製以下程式碼到到產品控制器。

<?php

namespace App\Http\Controllers;

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

class ProductController extends Controller
{
    public function index()
    {
        $products = auth()->user()->products;

        return response()->json([
            'success' => true,
            'data' => $products
        ]);
    }

    public function show($id)
    {
        $product = auth()->user()->products()->find($id);

        if (!$product) {
            return response()->json([
                'success' => false,
                'message' => 'Product with id ' . $id . ' not found'
            ], 400);
        }

        return response()->json([
            'success' => true,
            'data' => $product->toArray()
        ], 400);
    }

    public function store(Request $request)
    {
        $this->validate($request, [
            'name' => 'required',
            'price' => 'required|integer'
        ]);

        $product = new Product();
        $product->name = $request->name;
        $product->price = $request->price;

        if (auth()->user()->products()->save($product))
            return response()->json([
                'success' => true,
                'data' => $product->toArray()
            ]);
        else
            return response()->json([
                'success' => false,
                'message' => 'Product could not be added'
            ], 500);
    }

    public function update(Request $request, $id)
    {
        $product = auth()->user()->products()->find($id);

        if (!$product) {
            return response()->json([
                'success' => false,
                'message' => 'Product with id ' . $id . ' not found'
            ], 400);
        }

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

        if ($updated)
            return response()->json([
                'success' => true
            ]);
        else
            return response()->json([
                'success' => false,
                'message' => 'Product could not be updated'
            ], 500);
    }

    public function destroy($id)
    {
        $product = auth()->user()->products()->find($id);

        if (!$product) {
            return response()->json([
                'success' => false,
                'message' => 'Product with id ' . $id . ' not found'
            ], 400);
        }

        if ($product->delete()) {
            return response()->json([
                'success' => true
            ]);
        } else {
            return response()->json([
                'success' => false,
                'message' => 'Product could not be deleted'
            ], 500);
        }
    }
}
複製程式碼

測試

現在,我們的邏輯已經完成,讓我們開始測試。 我們將在 PHP 開發伺服器上測試它,但你可以根據需要使用虛擬主機。 執行以下命令以在 PHP 開發伺服器上提供應用程式。

php artisan serve
複製程式碼

現在讓我們用測試工具測試我們的API Postman.

註冊介面

Laravel Passport Authentication Register

登陸介面

Laravel Passport Authentication Login

詳情介面

在測試詳情介面或需要使用者進行身份驗證的任何 API 時,你需要指定兩個標頭請求頭資訊。 你必須在 Authorization 請求頭中將 token 指定為 Bearer token。 基本上,你必須將登入和註冊後收到的 token 拼到 Bearer 後面,當中空一個空格。

'headers' => [
    'Accept' => 'application/json',
    'Authorization' => 'Bearer '. $accessToken,
]
複製程式碼

Laravel Passport Authentication Details

產品列表介面

Passport Authentication Product Index

產品新增介面

Passport Authentication Product store

產品展示介面

Passport Authentication Product show

產品更新介面

Passport Authentication Product update

產品刪除介面

Passport Authentication Product delete

本教程的完整程式碼可以從 github 獲取 GitHub

文章轉自:learnku.com/laravel/t/2…
更多文章:learnku.com/laravel/c/t…

相關文章