TJ Weems
TJ Weems

Reputation: 1114

How To Use Passport In A Multi Tenant Setup In Laravel

Prerequisites:

  1. Laravel Version: 5.7
  2. Hyn/Multi-tenant Package 5.3
  3. Laravel Passport

So I have a Laravel app already using passport for authentication. Now currently when a user logs in I use the following controller to authorize and grant access token to user

public function login(Request $request)
    {
        $http = new \GuzzleHttp\Client;
        try {
            $response = $http->post(config('services.passport.login_endpoint'), [
                'form_params' => [
                    'grant_type' => 'password',
                    'client_id' => config('services.passport.client_id'),
                    'client_secret' => config('services.passport.client_secret'),
                    'username' => $request->username,
                    'password' => $request->password,
                ]
            ]);
            return $response->getBody();
        } catch (\GuzzleHttp\Exception\BadResponseException $e) {
            if ($e->getCode() === 400) {
                return response()->json('Invalid Request. Please enter a username or a password.', $e->getCode());
            } else if ($e->getCode() === 401) {
                return response()->json('Your credentials are incorrect. Please try again', $e->getCode());
            }
            return response()->json('Something went wrong on the server.', $e->getCode());
        }
    }

However A couple of things Are hard coded that will not work for multi tenant set up.

services.passport.client_id and services.passport.client_secret

They are generated for the single instance of the backend. But when I set up multi tenant each tenant will have there separate client_id and client_secret.

So The workflow I am wanting essentially looks like this

  1. I as the manager register a new backend instance for a tenant
  2. The hyn\multi-tenant package will then create a database for the new tenant
  3. The new database for that tenant will contain access tokens and cliet_secret

Up to here is complete and already functioning, below is the part I am trying to understand

  1. My front-end has a completely separate code base that communicates with the backend via API.
    1. so the user on the front end who belongs to the tenant instance will attempt to login using the login controller that I showed above, however the point of my post and the question I have is how can I dynamically call the client_id and client_secret based on the user\tenant database??

I know this is a lot to probably digest but if any body has ideas I am all ears. Thank you in advance!!

Upvotes: 3

Views: 1562

Answers (1)

Divya Shrestha
Divya Shrestha

Reputation: 51

The first thing to do is create a custom PassportClient, PassportAuthCode, PassportPersonalAccessClient, PassportToken model that is connected to your tenant connection

use Hyn\Tenancy\Traits\UsesTenantConnection;
use Laravel\Passport\AuthCode;

class PassportAuthCode extends AuthCode
{use UsesTenantConnection;}

use Hyn\Tenancy\Traits\UsesTenantConnection;
use Laravel\Passport\Client;

class PassportClient extends Client
{use UsesTenantConnection;}

use Hyn\Tenancy\Traits\UsesTenantConnection;
use Laravel\Passport\PersonalAccessClient;

class PassportPersonalAccessClient extends PersonalAccessClient
{use UsesTenantConnection;}

use Hyn\Tenancy\Traits\UsesTenantConnection;
use Laravel\Passport\Token;

class PassportToken extends Token
{use UsesTenantConnection;}

After creating this class, we need to tell a passport to use our custom implementation. Just add the following lines to your AuthServiceProvider file

Passport::useClientModel(PassportClient::class);
Passport::useTokenModel(PassportToken::class);
Passport::useAuthCodeModel(PassportAuthCode::class);
Passport::usePersonalAccessClientModel(PassportPersonalAccessClient::class);

Upvotes: 4

Related Questions