gnikyt / laravel-shopify

A full-featured Laravel package for aiding in Shopify App development
MIT License
1.24k stars 374 forks source link

Osiset\ShopifyApp\Exceptions\MissingShopDomainException #594

Closed vmbcarabbacan closed 3 years ago

vmbcarabbacan commented 4 years ago

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.

bassem-shoukry commented 4 years ago

same issue

extfoxDusan commented 4 years ago

Same issue here

bassem-shoukry commented 4 years ago

Any updates

Princeallan commented 4 years ago

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 commented 4 years ago

Yeah... same issue...

bnski commented 4 years ago

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

'secure' => true,
'same_site' => 'none',
extfoxDusan commented 4 years ago

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 commented 4 years ago

getting same error

tameemahmad commented 4 years ago

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

MohammadLareeb commented 4 years ago

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

awebartisan commented 4 years ago

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 commented 4 years ago

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

awebartisan commented 4 years ago

Not tested but following steps will do:

Hope it helps.

shota commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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

image

sunil209 commented 4 years ago

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 commented 4 years ago

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

sunil209 commented 4 years ago

Hi @awebartisan ,

Below is screenshot of APP url and Allowed redirections

image

awebartisan commented 4 years ago

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

sxzero commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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

oayoub84 commented 3 years ago

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

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 commented 3 years ago

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 commented 3 years ago

@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 commented 3 years ago

@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 commented 3 years ago

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(); }

gnikyt commented 3 years ago

Need logs and a step by step of how to reproduce.

Dwhyte commented 3 years ago

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.

jasontxf commented 3 years ago

Thanks @Dwhyte I didn't know we could test directly from Shopify Partner page!

Here's the position of the button if anyone is wondering!

Screenshot 2020-12-04 at 2 00 41 PM
mooezz999 commented 3 years ago

@Dwhyte Thanks man it worked

redamakhchan commented 3 years ago

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

mooezz999 commented 3 years ago

@makhchan Sadly I’m stuck with the redirecting issue at the moment. Tried chrome, firefox and opera didn’t solve the problem.

Dwhyte commented 3 years ago

@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 commented 3 years ago

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

Dwhyte commented 3 years ago

@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 commented 3 years ago

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 commented 3 years ago

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

yasir-naseer-tetralogicx commented 3 years ago

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 commented 3 years ago

@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 commented 3 years ago

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

reda-redimpact commented 3 years ago

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 commented 3 years ago

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 commented 3 years ago

@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 commented 3 years ago

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

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

redamakhchan commented 3 years ago

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 commented 3 years ago

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 commented 3 years ago

@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]
...