Создание REST API с аутентификацией

Создание rest api в Laravel

Ищете как создать RESTful API в Laravel? Если да, то я расскажу вам всё поэтапно, как создать полноценный API с аутентификацией с использованием Laravel Passport. API также известен как веб-служба.

На сегодняшний день, как мы знаем, Laravel является самым популярным фреймворком по причине своей безопасности. Поэтому многие разработчики выбирают его для разработки API мобильных приложений. Да, веб-службы очень важны при создании веб- и мобильных приложений, потому что вы можете создать одну базу данных для всех версий и работать с одинаковыми данными.

Если вы не знакомы с Laravel или не знаете, как начать создание API, не беспокойтесь, в этом уроке я шаг за шагом всё объясню. Вам просто нужно выполнить несколько этапов, чтобы получить API для регистрации, входа и работы с  товарами (добавление, обновление, удаление).

Шаг 1: Установка Laravel

Поскольку это пошаговый урок, прямо с нуля, то нам нужно сначала установить Laravel. Откройте командную строку и выполните команду:

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

Шаг 2: Установка Passport

Устанавливаем Passport с помощью менеджера пакетов Composer, запустите команду:

composer require laravel/passport

После успешной установки пакета нам необходимо получить миграции для создания новых таблиц в нашей базе данных. Запускайте команду:

php artisan migrate

Далее, для получения токенов безопасности, нам нужно запустить команду:

php artisan passport:install

Шаг 3: Настройка паспорта

В этом шаге мы должны провести настройку в трех местах: в модели, в сервис-провайдере и в файле конфигурации.

В модели мы добавим класс HasApiTokens,

В AuthServiceProvider мы добавим Passport::routes(),

В файле auth.php мы добавим настройки аутентификации api.

app/User.php

<?php

namespace App;
  
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Laravel\Passport\HasApiTokens;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements MustVerifyEmail
{
    use HasApiTokens, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];
}

app/Providers/AuthServiceProvider.php

<?php

namespace App\Providers;

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

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

return [
    .....
    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
        'api' => [
            'driver' => 'passport',
            'provider' => 'users',
        ],
    ],
    .....
]

Шаг 4: Добавляем таблицу товаров и Модель

Теперь нам нужно создать миграцию для таблицы товаров:

php artisan make:migration create_products_table

После выполнения этой команды вы найдете новый файл в папке database/migrations. Вам нужно вставить в него приведенный ниже код для создания таблицы товаров.

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateProductsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('products', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->text('detail');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */

    public function down()
    {
        Schema::dropIfExists('products');
    }
}

Теперь нужно запустить миграцию:

php artisan migrate

Таким образом мы создали таблицу «products». Теперь нужно сделать модель Product — создайте файл Product.php в папке app и поместите в него приведенный ниже код:

app/Product.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'detail'
    ];
}

Шаг 5. Создание маршрутов API

На этом этапе мы создадим маршруты API. Laravel предлагает для записи маршрутов веб-сервисов файл api.php. Давайте добавим новый маршрут к этому файлу.

routes/api.php

<?php

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/

Route::post('register', 'API\RegisterController@register');

Route::middleware('auth:api')->group( function () {
  Route::resource('products', 'API\ProductController');
});

Шаг 6: Создание файлов Контроллера

В этом шаге мы будем создавать новые контроллеры — BaseController, ProductController и RegisterController. Для них я создал новую папку «API» в папке контроллеров.

app/Http/Controllers/API/BaseController.php

<?php

namespace App\Http\Controllers\API;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller as Controller;

class BaseController extends Controller
{
    /**
     * success response method.
     *
     * @return \Illuminate\Http\Response
     */
    public function sendResponse($result, $message)
    {
    	$response = [
            'success' => true,
            'data'    => $result,
            'message' => $message,
        ];

        return response()->json($response, 200);
    }

    /**
     * return error response.
     *
     * @return \Illuminate\Http\Response
     */
    public function sendError($error, $errorMessages = [], $code = 404)
    {
    	$response = [
            'success' => false,
            'message' => $error,
        ];

        if(!empty($errorMessages)){
            $response['data'] = $errorMessages;
        }

        return response()->json($response, $code);
    }
}

app/Http/Controllers/API/ProductController.php

<?php

namespace App\Http\Controllers\API;

use Illuminate\Http\Request;
use App\Http\Controllers\API\BaseController as BaseController;
use App\Product;
use Validator;

class ProductController extends BaseController
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $products = Product::all();

        return $this->sendResponse($products->toArray(), 'Products retrieved successfully.');
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $input = $request->all();

        $validator = Validator::make($input, [
            'name' => 'required',
            'detail' => 'required'
        ]);

        if($validator->fails()){
            return $this->sendError('Validation Error.', $validator->errors());       
        }

        $product = Product::create($input);

        return $this->sendResponse($product->toArray(), 'Product created successfully.');
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $product = Product::find($id);

        if (is_null($product)) {
            return $this->sendError('Product not found.');
        }

        return $this->sendResponse($product->toArray(), 'Product retrieved successfully.');
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Product $product)
    {
        $input = $request->all();

        $validator = Validator::make($input, [
            'name' => 'required',
            'detail' => 'required'
        ]);

        if($validator->fails()){
            return $this->sendError('Validation Error.', $validator->errors());       
        }

        $product->name = $input['name'];
        $product->detail = $input['detail'];
        $product->save();

        return $this->sendResponse($product->toArray(), 'Product updated successfully.');
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy(Product $product)
    {
        $product->delete();

        return $this->sendResponse($product->toArray(), 'Product deleted successfully.');
    }
}

app/Http/Controllers/API/RegisterController.php

<?php

namespace App\Http\Controllers\API;

use Illuminate\Http\Request;
use App\Http\Controllers\API\BaseController as BaseController;
use App\User;
use Illuminate\Support\Facades\Auth;
use Validator;

class RegisterController extends BaseController
{
    /**
     * Register api
     *
     * @return \Illuminate\Http\Response
     */
    public function register(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'name' => 'required',
            'email' => 'required|email',
            'password' => 'required',
            'c_password' => 'required|same:password',
        ]);

        if($validator->fails()){
            return $this->sendError('Validation Error.', $validator->errors());       
        }

        $input = $request->all();
        $input['password'] = bcrypt($input['password']);
        $user = User::create($input);
        $success['token'] =  $user->createToken('MyApp')->accessToken;
        $success['name'] =  $user->name;

        return $this->sendResponse($success, 'User register successfully.');
    }
}

Теперь мы готовы к запуску RESTful API и Passport API. Давайте запустим наш пример — открывайте консоль и вводите команду:

php artisan serve

Убедитесь, что API использует следующие заголовки, как указано ниже:

'headers' => [
    'Accept' => 'application/json',
    'Authorization' => 'Bearer '.$accessToken,
]

Список адресов с методами

  1. Login: метод:GET, URL:http://localhost:8000/oauth/token
  2. Register: метод:GET, URL:http://localhost:8000/api/register
  3. List: метод:GET, URL:http://localhost:8000/api/products
  4. Create: метод:POST, URL:http://localhost:8000/api/products
  5. Show: метод:GET, URL:http://localhost:8000/api/products/{id}
  6. Update: метод:PUT, URL:http://localhost:8000/api/products/{id}
  7. Delete: метод:DELETE, URL:http://localhost:8000/api/products/{id}

Теперь вы можете запускать вышеприведенные адреса, как на скриншотах:

Вход API:
Login API

Регистрация API:
Register API

Список товаров API:
Product List API

Создание товара API:
Product Create API

Показ товара API:
Product Show API

Обновление товара API:
Product Update API

Удаление товара API:
Product Delete API

Автор: Hardik Savani
Перевод: Алексей Широков

Наш Телеграм-канал — следите за новостями о Laravel.