[Vuejs]-Solutions for managing multiple static websites using same code base

0đź‘Ť

  1. You should separate any reusable logic that can safely be applied to each website to a node module and you should host this yourself. For the views / custom features, those should be in their own repository. You can trigger pipelines on commit to automatically roll out continuous integration to specified servers on a repository-specific basis.

For #2, it’s more complex. One easy way is to make a new table called api_users, for instance. This will have 3 columns, id, tenant_id (or whatever your unique “tenant identifier” is) and token and expiry, where tenant_id is an FK to your tenants table. The token should just be a unique, long string.

Now you should pass that string on the frontend with any of your API Reqests. something like;

{
    headers: {
        'X-Tenant-Token': getTenantToken()
    }
}

Then in Laravel make new middleware for this:

php artisan make:middelware TenantValidityMiddleware

In the handle function, determine we need some logic:

if ($token = request()->headers()->get('X-Tenant-Token')) {

   app()->singleton(Tenant::class, function ($app) {
       return Tenant::whereHas('api_users', function(Builder $query){
          return $query->where('token', $token);
       })->firstOrFail();
   }); 

   return $next($request);
}

abort(401, 'Unauthorized access');

Now any dependency injected Tenant $tenant calls will automatically resolve your tenant for this API request.

Also, you can make sure that this is the case by adding:

session(['token' => $token]);

And you can add some safety to your container resolution logic in your AppServiceProvider:

$this->app->resolving(Tenant::class, function ($tenant, $app) {
    if (!$tenant->token === session('token') || auth()->user()->isAdmin()) {
        abort(401, 'Unauthorized access');
    }
});

This will help make sure that there are no forgery’s going on during requests.

(the token property of tenant is resolved like this:

public function getTokenAttribute()
{
    return $this->tokens()->first()->token;
}

And of course you need to define the token relationship:

public function tokens(): HasOne
{
    return $this->hasOne(ApiToken::class, 'api_users', 'tenant_id');
}
👤Ohgodwhy

Leave a comment