LoginSignup
0
0

More than 3 years have passed since last update.

Laravel + PassportでAPIを作成する

Posted at

Making an API with Laravel + Passport

以前の投稿を読んでいる場合は、Laravelプロジェクトのセットアップ方法を既に知っているので、それから続けて、パスポートをインストールしてJWT APIを作成します

If you have followed my previous posts, you already know how to setup a Laravel project, continuing from that, we will install passport to create an JWT Api

必要条件 / Requisites:

Laravel Project

Docker

Laravel/Passport

Laravel-Shovel

laravelプロジェクトフォルダー内に、一時的なdockerコンテナーを作成して「composer」を使用し、パスポートをインストールします

Inside the laravel project folder, we create a temporary docker container to use composerand install passport

docker run --rm -v $(pwd):/app composer require laravel/passport

この命令にはしばらく時間がかかります...完了したら、 docker-composeを開始できます

This instruction will take a while ...once done, we can start the docker-compose

sudo docker-compose up --build

実行されると、「http:// localhost /」に移動して確認できます

Once its running, we can verify by going to http://localhost/

新しい移行を実行し、パスポートをインストールします

We run the new migrations and Install passport

sudo docker-compose exec app-server php artisan migrate
sudo docker-compose exec app-server php artisan passport:install

これで、お気に入りのエディター(私の場合はPHPStorm)を使用してプロジェクトを開き、 Userモデルを編集してHasApiTokens特性を追加できます。

We can now open the project using our favorite editor, in my case PHPStorm, and edit the User model to add the HasApiTokens trait.

<?php

namespace App;

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

class User extends Authenticatable
{
    use HasApiTokens, Notifiable;

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

次に、 passport:routesAuthServiceProviderに追加します

Next we add the passport:routes to the AuthServiceProvider

<?php

namespace App\Providers;

use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
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でApi認証プロバイダーをパスポートに変更します

We change the Api Auth provider to passport in the config\auth.php

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

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

次に、 AuthControllerを作成します

Now we create our AuthController

docker-compose exec app-server php artisan make:controller API\\AuthController

この新しいコントローラーはdockerによって作成されたため、ファイルの書き込み許可を変更する必要がある場合があります

Since this new controller was made by docker, you might need to change the write permission of the file

sudo chown -R myUser:myUser mylaravelproject/

エディターで新しいAuthControllerを開くことができます。関数については、itsolutionstuff.com

ただし、機能に若干の変更が加えられています

Now we can open the new AuthController in our editor, as for the functions, I took the example from the itsolutionstuff.com

But with some slight changes in the functions

<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;

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

        if($validator->fails()){
            return response()->json(["error"=>$validator->errors()],422);
        }

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

        return response()->json($success);
    }

    /**
     * Login api
     *
     * @return \Illuminate\Http\Response
     */
    public function login(Request $request)
    {
        if(Auth::attempt(['email' => $request->email, 'password' => $request->password])){
            $user = Auth::user();
            $success['token'] =  $user->createToken('MyApp')-> accessToken;
            $success['name'] =  $user->name;

            return  response()->json([$success]);
        }
        else{
            return response()->json(["error"=>"Unauthorized"],422);
        }
    }
}

routes \ api.php内にルートを追加します

Add the routes inside routes\api.php

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

お気に入りのRESTクライアントを使用して、登録とログインをテストできます。「不眠症」を使用しています

You can test the register and login, using your favorite REST client, I'm using insomnia

http://localhost/api/register
{
    "name":"My Name",
    "email":"secremeail@email.com",
    "password":"securepassword",
    "password_confirmation":"securepassword"
}
http://localhost/api/login
{
    "email":"secremeail@email.com",
    "password":"securepassword"
}

これで、基本的なAPIを実装しましたが、より良い応答をするために、以下を使用します。

With this, we have implemented our basic API, but to make a better response, we use:

laravel-shovel

より良いAPI応答を行うためのライブラリです。

Is a library to make better API responses.

インストールする前に、 docker-composeを停止し、一時的なcomposerコンテナを実行します。

Before installing it, we stop docker-compose and run a temporary composer container.

docker run --rm -v $(pwd):/app composer require stephenlake/laravel-shovel

ミドルウェア内のルートをグループ化します

We group the routes inside the middleware

Route::group(['middleware' => ['ApiRequest',"ApiResponse"]],function (){
    Route::post('register', 'API\AuthController@register');
    Route::post('login', 'API\AuthController@login');
});

すべてのAuthController応答を通常の応答に変更する必要があります

We have to change all the AuthController responses to normal resposes

<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;

class AuthController extends Controller
{

    public function register(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'name' => 'required',
            'email' => 'required|email',
            'password' => 'required|confirmed',
            'password_confirmation' => 'required|same:password',
        ]);

        if($validator->fails()){
           return response()->json(["messages"=>$validator->errors()],422)
               ->withMeta("message","Validation error");
        }

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

        return response($success);

    }


    public function login(Request $request)
    {
        $credentials = [
            'email' => $request->email,
            'password' => $request->password
        ];

        if (auth()->attempt($credentials)) {
            $token = auth()->user()->createToken('MyApp')->accessToken;
            return response(["token"=>$token]);
        } else {
            throw new \Exception("Invalid Credentials",422);
        }
    }
}

また、「app / Exceptions / handler.php」を処理する例外にjson応答を追加します

Also add a json response in the expection handled app/Exepctions/handler.php

public function render($request, Exception $exception)
    {
        if($request->acceptsJson())
        {
            return response()
                ->json(["messages"=>$exception->getMessage()],500)
                ->withMeta("message","internal server error");
        }
        return parent::render($request, $exception);
    }

このライブラリは、メタヘッダーを追加するすべてのAPI応答を標準化します

This library will standarize all api responses adding meta headers

{
  "meta": {
    "code": 200,
    "status": "success",
    "message": "OK"
  },
  "data": {
    "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiIxIiwianRpIjoiMTMzYzU3NjVlZmJjYTdmODQ0NDdlMTE4ZWUyZDc1YWI5YzY0MmQ3NTE2MjIzNWM1Y2FjNDNlNjI5ZDIyMzU1MzMzMzY1M2U2Yjc2ZTJhNzIiLCJpYXQiOjE1NzcxNTQwMzcsIm5iZiI6MTU3NzE1NDAzNywiZXhwIjoxNjA4Nzc2NDM3LCJzdWIiOiIxIiwic2NvcGVzIjpbXX0.KIoArr6X69eRLDluWWgEOS5gAlLmLxtYKhMURgzsmgmLooVV6EJDHGx11gnQ7_WmagtbredLabHXeSks6DQ2A8tGeqFyrVxnCRddAySxHDxhzF0VF2wF9rn_1OduDcC3xOVdrXPj-VkxToHLyW3e6A714XSTxHgzynEKBh2JtDIRN3lCt13_1F8iD9ocGHPLBrW-XFhV4Iw2atSyL8N5qQH29wsopwWZCoTqqAN2whgfylyCTlXFAcQWe0AOJEzc39jpTudkiSXAKKFuS1hCjLYYdiuae-NJGOTutDD3CzFjYrO-Kvq3-QBX7go4uNftOVwuARsvlBuyCfPbpzCM8FVfuZCEHMv7YODCrCs2s305PvsGAsIIcKB_9_dpx0nO-lZy9_Hsn6HKAztCkLBNQponLAM10pah36xaq5c_mOwRMIltRArfDi-QuteIP4XUYXJXDV96bw2BQGNlybbOU0z7x7ocLmlP7xh4NBZFjUs5eM02U6eJykewxr8UpIkoyi6N3-ZxKKhdIWfeW6jRFe7IHlKQ2QTR1Hp33zGPlwTIW8dTe8UYo_FXdQojsFV7uxc9GUUDFimrJT3cem6JvcUEWsQtbxRv3tyyMST4P5gZpr-bANS2z6DiseuQRjHU9ZNYX9rm62GS8Wo_sNXxbfayTrFk6mBsuNn33kY1T8o"
  }
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0