Skip to content
This repository has been archived by the owner on Nov 30, 2022. It is now read-only.

Osiset\ShopifyApp\Exceptions\MissingShopDomainException #594

Closed
vmbcarabbacan opened this issue Sep 27, 2020 · 64 comments
Closed

Osiset\ShopifyApp\Exceptions\MissingShopDomainException #594

vmbcarabbacan opened this issue Sep 27, 2020 · 64 comments
Labels
needs-info More information required

Comments

@vmbcarabbacan
Copy link

I am getting MissingShopDomainException upon running the app. This is a fresh laravel 8.6.0

Please provide any relevant information about your setup. This is important in case the issue is not reproducible except for under certain conditions.

  • Package Version: 13.0
  • Laravel Version: 8.6.0
  • PHP Version: 7.3
  • Using a toolset (Docker, Laradock, Vagrant, etc.):
@bassem-shoukry
Copy link

same issue

@extfoxDusan
Copy link

Same issue here

@bassem-shoukry
Copy link

Any updates

@Princeallan
Copy link

Princeallan commented Sep 29, 2020

Same issue, and this is the issue with authentication by Shopify middleware, this error happens when you are not logged in and when logged in you will experience another error of redirecting to shopify. I haven't figured out the solution but it has to do with redirecting the URL in the homepage. I think it's in window['app-bridge'].actions.Redirect = (AppBridge.actions.Redirect)

@bnski
Copy link

bnski commented Sep 29, 2020

Yeah... same issue...

@bnski
Copy link

bnski commented Sep 29, 2020

I found some temporary relief by making the following changes to my Session config:

'secure' => true,
'same_site' => 'none',

@extfoxDusan
Copy link

I found some temporary relief by making the following changes to my Session config:

'secure' => true,
'same_site' => 'none',

Does not work for me. It's the same as before.

@tameemahmad
Copy link

getting same error

@tameemahmad
Copy link

this is the issue with latest version of laravel now i installed laravel 7 and then follow the docs and app is running

@MohammadLareeb
Copy link

@tameemahmad mine is not working even after a fresh installation of laravel 7. How did you make it work?

@awebartisan
Copy link
Contributor

awebartisan commented Oct 3, 2020

In v13.0 , Login route and view has been removed. Home route expects a myshopify domain which is missing. So you would have to implement the Login functionality yourself to get myshopify domain and then send it to Home route.

Or

Hit your app url like: https://example.com/home?shop=shop.myshopify.com by passing shop parameter in query string.

@MohammadLareeb
Copy link

MohammadLareeb commented Oct 3, 2020

@awebartisan How to implement login functionality? Please, If you can guide me that would be great!

@awebartisan
Copy link
Contributor

Not tested but following steps will do:

  • Create a /login route
  • Create a login.blade.php with a form. Input with name="shop" to get the .myshopify.com domain of a store and a submit button which will submit the form to home route of your app.
  • Add auth middleware along with auth.shopify to your home route. This will redirect user to login page that you created.

Hope it helps.

@shota
Copy link

shota commented Oct 8, 2020

In my case, redirection to http:// scheme URL cause this problem. Adding forceScheme line to app/Providers/AppServiceProvider.php fixes this problem.

    public function boot()
    {
        \URL::forceScheme('https');
    }

I think it's because I use ngrok to serve https. HTTP_X_FORWARDED_PROTO header value is 'https' but laravel8 doesn't use the value and Redirect::route('home') returns http scheme URL. I hope this helps

@mohinpatwary
Copy link

mohinpatwary commented Oct 9, 2020

Hello @awebartisan,
I've created login.blade.php here.

image

image

Also, I've added auth.shopify in the middleware.

image

Can you please guide me, What code will I add in login.blade.php? I am new to the laravel.

Thanks in advance

@sunil209
Copy link

Having the same issue with Laravel 8. Can any one please guide. I am new with Laravel.

image

@sunil209
Copy link

Hi @awebartisan,

I followed the steps as you had suggested

Create a /login route
Create a login.blade.php with a form. Input with name="shop" to get the .myshopify.com domain of a store and a submit button which will submit the form to home route of your app.
Add auth middleware along with auth.shopify to your home route. This will redirect user to login page that you created.

After adding these --
https://laravel.test/login
by filling the shop name it is redirecting me to the shopify properly and after installing the app when I am redirecting back to https://laravel.test/authenticate where It is just rotating rotating ... I have checked shopify-app.php looks something missing.

Can you please suggest

@awebartisan
Copy link
Contributor

Hi @sunil209 , what does your App Url and Allowed redirection URL(s) look like in App setting on partner dashboard?

@sunil209
Copy link

Hi @awebartisan ,

Below is screenshot of APP url and Allowed redirections

image

@awebartisan
Copy link
Contributor

@sunil209 it would be better to open a separate issue for this. With shopify-app.php file contents and other appropriate information.

@sxzero
Copy link

sxzero commented Oct 20, 2020

this is the issue with latest version of laravel now i installed laravel 7 and then follow the docs and app is running

I'm ussing "laravel/framework": "^7.24" but I still have the same error.

@sxzero
Copy link

sxzero commented Oct 20, 2020

In v13.0 , Login route and view has been removed. Home route expects a myshopify domain which is missing. So you would have to implement the Login functionality yourself to get myshopify domain and then send it to Home route.

Or

Hit your app url like: https://example.com/home?shop=shop.myshopify.com by passing shop parameter in query string.

I hit direct to https://domain.local?shop=shop.myshopify.com and it works! Thanks,

"laravel/framework": "^7.24"
"osiset/laravel-shopify": "^14.0"

@gnanakeethan
Copy link

gnanakeethan commented Oct 28, 2020

Hi, Sorry for the wrong comment earlier.

This issue has to be sorted with two routes.

in web.php (routes)

Route::get('/', function () {
    return view('welcome');
})->middleware(['auth'])->name('home');
Route::get('/shop', function () {
    return redirect()->route('home');
})->middleware(['auth.shopify'])->name('shop');

login blade

<form method="GET" action="{{ route('shop') }}">

I hope this helps.

@awebartisan I hope this can be documented in the installation.

@gnikyt
Copy link
Owner

gnikyt commented Nov 1, 2020

@gnanakeethan Feel free to make a wiki entry for others.

@oayoub84
Copy link

Hi, first of all. Thanks to @osiset for his awesome job. You saved us a lot of time in Shopify apps development 🙏.

The problem with @gnanakeethan solution (which is working fine) is that it doesn't solve the main problem, which is when we access the /shop route directly we will get the same error. the best solution is to catch the exception and redirect to the login page (get ride of the error completely). For that we must not use the auth middleware, just auth.shopify, because they do the same thing in different ways, so there will be a conflict if both used (Unless you handle them separately).

For me this is what i did.

In web.php (routes)

Route::get('/login', function () {
    if (Auth::user()) {
        return redirect()->route('home');
    }
    return view('login');
})->name('login');

Route::middleware(['auth.shopify'])->group(function () {
    Route::get('/', function () {
        return view('welcome');
    })->name('home');

    // Other routes that need the shop user
});

In login.blade.php

<form method="GET" action="{{ route('home') }}">
   <input type="text" name="shop"/>
   <button type="submit">Submit</button>
</form>

In app/Exceptions/Handler.php

public function render($request, Throwable $exception)
{
    if ($exception instanceof MissingShopDomainException) {
        return Redirect::secure('login');
    }

    return parent::render($request, $exception);
}

And finally, don't forget the tip from @shota (not mandatory), which well help in local development using ngrokor localtunnel to always have https scheme.
In app/Providers/AppServiceProvider.php

public function boot()
{
    URL::forceScheme('https');
}

I hope this helps if the @gnanakeethan solution doesn't sweet your needs.

@kantsverma
Copy link

kantsverma commented Nov 25, 2020

I tried everything but still the same issues for Laravel 8. I am facing the issues only in case i am not logged to Shopify admin if i am already logged in its working fine. I mean its not asking for login page like the other app. May be somewhere need to check for auth. I might be wrong because i am new to Shopify and my app is not public and I am hitting the domain URL directly from browser where i am not logged in with Shopify admin. Please guide :)

@oayoub84
Copy link

@kantsverma just make sure that you have a route named 'login' (which is public, doesn't have any middleware) in routes, and the render function in your ExceptionHandler. if the error still persist, you can share with me a basic project that has the problem and i will check it for you.

@kantsverma
Copy link

kantsverma commented Nov 26, 2020

@Masix i followed the all steps you mentioned then i got below error
Error
Class 'App\Providers\URL' not found
1st -Error

Then i add this use Illuminate\Support\Facades\URL; In app/Providers/AppServiceProvider.php

After that i run the the commands
php artisan optimize
php artisan route:clear

But still the same error , but error are only in case of i am not logged in to Shopify App admin else its working fine.
2nd-error

@kantsverma
Copy link

kantsverma commented Nov 26, 2020

After spending few hours i fixed the issues. Please follow the steps

  1. In case of not verifyHmac it go to class AuthShopify to call method handle
  2. Where this is called return $this->handleBadVerification($request, $domain);
  3. Inside method handleBadVerification() if auth is empty so it call class MissingShopDomainException and this class is empty and nothing handled inside class
    if ($domain->isNull()) {
    // We have no idea of knowing who this is, this should not happen
    throw new MissingShopDomainException();
    }
  4. Please replace below snippets inside method handleBadVerification() and it will work fine
    if ($domain->isNull()) {
    // We have no idea of knowing who this is, this should not happen
    return redirect()->route('login'); // fix the bugs to rediec to login page if auth emtpty
    //throw new MissingShopDomainException();
    }

@Dwhyte
Copy link

Dwhyte commented Dec 27, 2020

@makhchan @mooezz999 I was able to replicate the same issue when I have the "forceRedirect" set to false in the default.blade.php file script section.

Screen Shot 2020-12-26 at 5 04 59 PM

Once that is "false", I have my test app running outside my shopify store via ex: myshopifyapp.test in chrome browser, and also still viewing the test app inside the shopify store instance in another separate tab.

I do get redirected to Osiset\ShopifyApp\Exceptions\MissingShopDomainException error page when both app instances are open, and I'm viewing the same page/route in both apps. One of the apps will send an MissingShopDomainException error at random.

This is all I could reproduce on my side. So I just pick which one I want to development in, or set "forceRedirect" to true to just have your local app address redirect to your shopify store app and use that instead.

@mooezz999
Copy link

@Dwhyte Where did you get this default.blade.php code from? Can you send me the code in default.blade.php please?

@Dwhyte
Copy link

Dwhyte commented Dec 27, 2020

@mooezz999 you already have it. All you need to do is run this command in your app terminal - php artisan vendor:publish

then select the number option for "shopify-views". This will generate a vendor folder in your views directory with all those blade files. :)

@redamakhchan
Copy link

I'm also stuck with the redirect issue.
I think it is due to missing $shop param on one of input, header or referer, which cause $domain to be null

vendor/osiset/laravel-shopify/src/ShopifyApp/Http/Middleware/AuthShopify.php:68

    public function handle(Request $request, Closure $next)
    {
        // Grab the domain and check the HMAC (if present)
        $domain = $this->getShopDomainFromData($request);
        ....

And That cause the MissingShopDomainException :
vendor/osiset/laravel-shopify/src/ShopifyApp/Http/Middleware/AuthShopify.php:337

    private function handleBadVerification(Request $request, ShopDomainValue $domain)
    {
        if ($domain->isNull()) {
            // We have no idea of knowing who this is, this should not happen
            throw new MissingShopDomainException();
        }
        ....

Hope someone can do a PR for this one soon, @osiset will appreciate your support on this, really blocked many developers as I see.

@gnikyt
Copy link
Owner

gnikyt commented Dec 29, 2020

So is this only happening when you click on a route inside your app?

@yasir-naseer-tetralogicx

My app is working just fine in chrome browser. if i click a route inside app it redirects me to expected page without any issues, but as soon as i move to some other browser like firefox and i click some route within it is throwing the same exception. (I'm using "osiset/laravel-shopify": "15.*" )

@gnikyt
Copy link
Owner

gnikyt commented Dec 29, 2020

@yasir-naseer-tetralogicx

So if I understand.

Chrome: You open app... all is fine. You click on a route inside the app... all is fine.

Firefox: You open app... all is fine. You click on a route inside the app... error shows.

Is that correct?

Edit: To me it sounds like either the Laravel Session is lost, or I'm not checking for it in the middleware, which I'm pretty sure I am. If I am checking, then this goes back to the cookie issues I believe.

@yasir-naseer-tetralogicx

@osiset yes this is right, its happening on firefox for me

@reda-redimpact
Copy link

I confirm for FF, I didn't test on chrome will do and see if it is working fine and confirm back here.
But for FF just navigating inside app to different route cause the issue, yes I confirm.

@raihan004
Copy link

Hi, first of all. Thanks to @osiset for his awesome job. You saved us a lot of time in Shopify apps development 🙏.

The problem with @gnanakeethan solution (which is working fine) is that it doesn't solve the main problem, which is when we access the /shop route directly we will get the same error. the best solution is to catch the exception and redirect to the login page (get ride of the error completely). For that we must not use the auth middleware, just auth.shopify, because they do the same thing in different ways, so there will be a conflict if both used (Unless you handle them separately).

For me this is what i did.

In web.php (routes)

Route::get('/login', function () {
    if (Auth::user()) {
        return redirect()->route('home');
    }
    return view('login');
})->name('login');

Route::middleware(['auth.shopify'])->group(function () {
    Route::get('/', function () {
        return view('welcome');
    })->name('home');

    // Other routes that need the shop user
});

In login.blade.php

<form method="GET" action="{{ route('home') }}">
   <input type="text" name="shop"/>
   <button type="submit">Submit</button>
</form>

In app/Exceptions/Handler.php

public function render($request, Throwable $exception)
{
    if ($exception instanceof MissingShopDomainException) {
        return Redirect::secure('login');
    }

    return parent::render($request, $exception);
}

And finally, don't forget the tip from @shota (not mandatory), which well help in local development using ngrokor localtunnel to always have https scheme.
In app/Providers/AppServiceProvider.php

public function boot()
{
    URL::forceScheme('https');
}

I hope this helps if the @gnanakeethan solution doesn't sweet your needs.

this one solve the issues for me

@reda-redimpact
Copy link

@raihan004 the above code just redirects to login page in case of MissingShopDomainException, it doesn't fix the real issue, why we face MissingShopDomainException when navigating on the app..
I face this issue on both Chrome and FireFox. windows + ubuntu.

@reda-redimpact
Copy link

@osiset
For getShopDomainFromData, exactly INPUT, HEADER & REFERER options.

  • First load just after login :

INPUT is filled with info
HEADER is null
REFERER is null

  • First navigation to different route :

INPUT is null
HEADER is null
REFERER is filled this time

  • 2nd navigation :

INPUT is null
HEADER is null
REFERER is null

I think also it is related to lost a session where this info are searched for..

@redamakhchan
Copy link

Looking more into the issue, Single Page applications will not have this issue.

Some related (old) subjects :

Getting hmac from cookies or custom session can be a solution.

@gnikyt
Copy link
Owner

gnikyt commented Dec 30, 2020

Hmm I think the issue may be pulling the domain from the data. If they are logged in, I should pull the domain from the user model...

@redamakhchan Are you able to confirm if the user is logged in on your first and second navigation?

If you open src/ShopifyApp/Http/Middleware/AuthShopify.php and at line 84 (blank line), add:

Log::info(json_encode($this->shopSession->getShop()));.

If the user session is still active, the log should show, and in that case, the error lies there in trying to pull from data when it should pull from the user model first, then data as a secondary.

@redamakhchan
Copy link

redamakhchan commented Dec 30, 2020

@osiset I confirm,
I can see user object on 1st time, just after login (before redirect to myshopify.com)
When redirected and the app embedded it shows null
1st time I navigate it shows also null
2nd navigation MissingShopDomainException

Logs :

[2020-12-30 16:06:57] local.INFO: {"id":1,"name":"****.myshopify.com","email":"shop@****.myshopify.com","email_verified_at":null,"created_at":"2020-12-25T13:33:41.000000Z","updated_at":"2020-12-30T10:41:19.000000Z","shopify_grandfathered":0,"shopify_namespace":null,"shopify_freemium":0,"plan_id":null,"deleted_at":null}  
[2020-12-30 16:07:02] local.INFO: null  
[2020-12-30 16:07:02] local.INFO: null  
[2020-12-30 16:07:39] local.ERROR:  {"exception":"[object] (Osiset\\ShopifyApp\\Exceptions\\MissingShopDomainException(code: 0):  at ***/vendor/osiset/laravel-shopify/src/ShopifyApp/Http/Middleware/AuthShopify.php:342)
[stacktrace]
...

@gnikyt
Copy link
Owner

gnikyt commented Dec 30, 2020

Hmm thanks. Ill try to reproduce.

@gnikyt
Copy link
Owner

gnikyt commented Dec 30, 2020

Though my testing I can confirm this is a cookie issue. The cookie is never set, this Auth::user is always null.

I've tried to quickly debug this by:

  1. Creating a middleware to check for a test cookie
  2. If test cookie is not existing, redirect full-page to a path and set the test cookie
  3. Redirect back to app

I can see the samesite test cookie is set, however, when going back into the app, cookies are not there and browser warns of a third party attempting to set cookies.

I'll close this for #522 ... I do not have a solution for this right now, I need help on this, but at least I'm able to reproduce.

@gnikyt gnikyt closed this as completed Dec 30, 2020
@sagar-itt
Copy link

\URL::forceScheme('https');

URL import package name?

@KevinSHansen
Copy link

Anything new on this?

Still got the issue.
Osiset\ShopifyApp\Exceptions\MissingShopDomainException

@sagar-itt
Copy link

sagar-itt commented Feb 23, 2021 via email

@haseebbutt1999
Copy link

Everything works as normal for me. Keep everything the same based on the https://github.com/osiset/laravel-shopify/wiki/Installation guide.
I'm using Laravel v8
!! Just make sure to create a development store in your https://partners.shopify.com/ account.
When you create an app, go back into the main home page of your app and scroll down to the bottom.
Select "Test your app". Then hit "Select Store".
At that point, either create a development store if you haven't done so already and select "install app" on the far right of your selected created store.
You will reach another page telling you to finally install your app into your development store.
Watch this video and follow along carefully. - https://www.youtube.com/watch?v=7U_skSqlI1E&list=PLB4AdipoHpxbE0ldfsNobTSZm2tUBW9GR&index=2&t=437s
Hope this helps anyone who is stuck.

@Dwhyte The installation & login to store works fine, issue is when you navigate to other routes, it takes you back to login page MissingShopDomainException.
@mooezz999 @jasontxf is navigation to other pages works fine for you ?

My case am connected to the app on store, I move to products page it works, 2nd time I click any link it shows the exception MissingShopDomainException

Same my issue, are you getting any solution about this issue?

@rewaza
Copy link

rewaza commented Mar 25, 2021

Everything works as normal for me. Keep everything the same based on the https://github.com/osiset/laravel-shopify/wiki/Installation guide.
I'm using Laravel v8
!! Just make sure to create a development store in your https://partners.shopify.com/ account.
When you create an app, go back into the main home page of your app and scroll down to the bottom.
Select "Test your app". Then hit "Select Store".
At that point, either create a development store if you haven't done so already and select "install app" on the far right of your selected created store.
You will reach another page telling you to finally install your app into your development store.
Watch this video and follow along carefully. - https://www.youtube.com/watch?v=7U_skSqlI1E&list=PLB4AdipoHpxbE0ldfsNobTSZm2tUBW9GR&index=2&t=437s
Hope this helps anyone who is stuck.

@Dwhyte The installation & login to store works fine, issue is when you navigate to other routes, it takes you back to login page MissingShopDomainException.
@mooezz999 @jasontxf is navigation to other pages works fine for you ?
My case am connected to the app on store, I move to products page it works, 2nd time I click any link it shows the exception MissingShopDomainException

Same my issue, are you getting any solution about this issue?

Same issue. Stuck on error: Osiset\ShopifyApp\Exceptions\MissingShopDomainException

@sagar-itt
Copy link

sagar-itt commented Mar 26, 2021 via email

@redamakhchan
Copy link

Hello everyone,

I faced this issue also, and I did fix by setting same_site param to none at the end of config/session.php

    /*
    |--------------------------------------------------------------------------
    | Same-Site Cookies
    |--------------------------------------------------------------------------
    |
    | This option determines how your cookies behave when cross-site requests
    | take place, and can be used to mitigate CSRF attacks. By default, we
    | will set this value to "lax" since this is a secure default value.
    |
    | Supported: "lax", "strict", "none", null
    |
    */

    'same_site' => 'none',

Happy coding.

@squatto
Copy link
Contributor

squatto commented Mar 28, 2021

Rather than changing your app's cookie settings, you can instead just trigger a redirect (or do anything you want) whenever MissingShopDomainException is thrown.

In app/Exceptions/Handler.php in the register() method, register the exception as renderable and then put whatever your handling code is in the callback.

For example, in my app I am redirecting to a route that displays a message to the user letting them know that their login can't be verified, and instructing them to reload our app from their Shopify admin:

public function register(): void
{
    // redirect to the "unable to verify your login" error message
    $this->renderable(function (MissingShopDomainException $e) {
        return redirect()->route('apps.shopify.no-auth');
    });
}

One important thing to remember is that the user is not authenticated when they access the route that you redirect them to, so you will need to register the route without the auth.shopify middleware. I would recommend that you also register the route without the itp middleware, since you don't need to worry about ITP at that point.

I manually register all of the app routes (instead of letting the package register them) and I've broken them into separate files, but I'll put this here in case anybody is curious how to accomplish what I said in the previous paragraph:

Route::middleware('web')
     ->group(function () {
         // the user isn't logged in
         require base_path('routes/apps/shopify/no-auth.php');

         Route::middleware('itp')
              ->group(function () {
                  require base_path('routes/apps/shopify/itp.php');

                  Route::middleware('auth.shopify')
                       ->group(function () {
                           // ...authenticated app routes...
                       });
              });
     });

You will also need to make sure that your views recognize that the user isn't logged in and don't attempt to display shop info, user info, etc. You can do that with @auth ... @endauth and @guest ... @endguest

@rewaza
Copy link

rewaza commented Mar 29, 2021

Thank you all. When I solved this issue, I faced another one (same site issue) I moved app from local server to heroku and everything works fine. Thanks.

@otmaneomry
Copy link

Thanks a lot @oayoub84 it worked for me

@arnedeutscher
Copy link

Hi, first of all. Thanks to @osiset for his awesome job. You saved us a lot of time in Shopify apps development 🙏.

The problem with @gnanakeethan solution (which is working fine) is that it doesn't solve the main problem, which is when we access the /shop route directly we will get the same error. the best solution is to catch the exception and redirect to the login page (get ride of the error completely). For that we must not use the auth middleware, just auth.shopify, because they do the same thing in different ways, so there will be a conflict if both used (Unless you handle them separately).

For me this is what i did.

In web.php (routes)

Route::get('/login', function () {
    if (Auth::user()) {
        return redirect()->route('home');
    }
    return view('login');
})->name('login');

Route::middleware(['auth.shopify'])->group(function () {
    Route::get('/', function () {
        return view('welcome');
    })->name('home');

    // Other routes that need the shop user
});

In login.blade.php

<form method="GET" action="{{ route('home') }}">
   <input type="text" name="shop"/>
   <button type="submit">Submit</button>
</form>

In app/Exceptions/Handler.php

public function render($request, Throwable $exception)
{
    if ($exception instanceof MissingShopDomainException) {
        return Redirect::secure('login');
    }

    return parent::render($request, $exception);
}

And finally, don't forget the tip from @shota (not mandatory), which well help in local development using ngrokor localtunnel to always have https scheme.
In app/Providers/AppServiceProvider.php

public function boot()
{
    URL::forceScheme('https');
}

I hope this helps if the @gnanakeethan solution doesn't sweet your needs.

This works for me. But instead $exception instanceof MissingShopDomainException i used $exception instanceof \Osiset\ShopifyApp\Exceptions\MissingShopDomainException for functionality.

@AryanKumar
Copy link

If you are using larave 8 and want to handle the exception "MissingShopDomainException" then you can handle this exception using handler.php in laravel.

Go to app->Exceptions->Handler and write below code:

use Osiset\ShopifyApp\Exceptions\MissingShopDomainException;
use Illuminate\Support\Facades\Redirect;

and inside function register write:
$this->renderable(function(MissingShopDomainException $e){
return Redirect::to('https://www.shopify.com/in/login');
});

This will redirect to the shopify login page when anyone will try to hit the base url without login.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
needs-info More information required
Projects
None yet
Development

No branches or pull requests