diff --git a/README.md b/README.md index 0221f76..d9b7350 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,28 @@ Setup alias for the Facade 'Shopify' => ClarityTech\Shopify\Facades\Shopify::class, ], ``` +## Set shopify app authentication + +Update config/app.php with below code and in routes add `auth:shopify` as middleware + +```php5 + +'guards' => [ + ... + 'shopify' => [ + 'driver' => 'shopify-auth', + 'provider' => 'shops', + ], +], + +'providers' => [ + ... + 'shops' => [ + 'driver' => 'eloquent', + 'model' => App\Models\Shop::class, + ] +], +``` ## Set credendials diff --git a/composer.json b/composer.json index 6ae057f..a5db1d7 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,8 @@ "extra": { "laravel": { "providers": [ - "ClarityTech\\Shopify\\ShopifyServiceProvider" + "ClarityTech\\Shopify\\ShopifyServiceProvider", + "ClarityTech\\Shopify\\AuthServiceProvider" ], "aliases": { "Shopify": "ClarityTech\\Shopify\\Facades\\Shopify" diff --git a/src/Shopify/AuthServiceProvider.php b/src/Shopify/AuthServiceProvider.php new file mode 100644 index 0000000..ea97ed6 --- /dev/null +++ b/src/Shopify/AuthServiceProvider.php @@ -0,0 +1,88 @@ + 'App\Policies\ModelPolicy', + ]; + + /** + * Register any authentication / authorization services. + * + * @return void + */ + public function boot() + { + $this->registerPolicies(); + + Auth::viaRequest('shopify-auth', function (Request $request) { + $shop = null; + $user_provider = Auth::createUserProvider('shops'); + $class = $user_provider->getModel(); + + if($class){ + $object = new $class(); + + if($object){ + if ($request->has('token')) { + $token = $request->token; + $key = config('shopify.secret'); + $tokenParts = explode(".", $token); + $tokenPayload = base64_decode($tokenParts[1]); + $jwtPayload = json_decode($tokenPayload); + + if ($this->verifyJwtToken($token, $key) && $jwtPayload) { + $myshopify_domain = Str::replaceFirst('https://', '', $jwtPayload->dest); + + $shop = $user_provider->retrieveByCredentials([ + $object->username() => $myshopify_domain + ]); + } + } elseif ($request->has('shop') && $request->has('hmac')) { + if (Shopify::verifyRequest($request->all())) { + $shop = $user_provider->retrieveByCredentials([ + $object->username() => $request->shop + ]); + } + } + } + } + return $shop; + }); + } + + function verifyJwtToken($token, $key) + { + $tokenParts = explode(".", $token); + $data = $tokenParts[0] . "." . $tokenParts[1]; + $hmc = hash_hmac('sha256', $data, $key, true); + $base64UrlSignature = $this->base64UrlEncode($hmc); + if ($base64UrlSignature == $tokenParts[2]) { + return true; + } else { + return false; + } + } + + function base64UrlEncode($text) + { + return str_replace( + ['+', '/', '='], + ['-', '_', ''], + base64_encode($text) + ); + } +} diff --git a/src/Shopify/Contracts/ShopifyShop.php b/src/Shopify/Contracts/ShopifyShop.php index ce5ae0d..560ea7d 100644 --- a/src/Shopify/Contracts/ShopifyShop.php +++ b/src/Shopify/Contracts/ShopifyShop.php @@ -9,4 +9,6 @@ public function getShopifyId() : int; public function getShopToken() : string; public function getShopifyDomain() : string; + + public function username() : string; } diff --git a/src/Shopify/ShopifyServiceProvider.php b/src/Shopify/ShopifyServiceProvider.php index 8c2e0d1..e9f765f 100644 --- a/src/Shopify/ShopifyServiceProvider.php +++ b/src/Shopify/ShopifyServiceProvider.php @@ -100,7 +100,7 @@ private function publishJobs(): void // Job publish $this->publishes( [ - __DIR__.'/Jobs/AppUninstalledJob.php' => "{$this->app->path()}/Jobs/AppUninstalledJob.php", + __DIR__.'/Jobs/AppUninstalledJob.php' => app_path("Jobs/AppUninstalledJob.php"), ], 'shopify-jobs' );