I've spent a lot of time looking through the docs, and I wonder if anyone can verify that the proposed design for my project works.
The background is that my client has a shopify merchant account, and processes sales etc through the standard mechanisms. They want an "app" that allows some features related to the product they're selling via shopify, but that will require access to an API (provided by me). I'm proposing creating an ASP.NET MVC application talking to an API (all Azure hosted) - so far so simple. However, the client would like his customers to use their Shopify logins to access the new application.
The normal flow for this would be to leverage OAuth / OpenId connect and treat Shopify as an Identity Provider, and on hitting any pages in the custom app, bounce to Shopify (most likely by using the Authorisation Code flow and requesting OpenID scope to pull user info (names etc) and grab a bearer token which I'd then use to call my API on behalf of the user).
However, as I understand the docs, this isn't a supported use case in Shopify - the auth code flow can be used but only to grant access to internal (private?) Apps by the merchant (not customer logins). It does appear however that I can essentially log a user in to the Shopify storefront API using this mechanism https://shopify.dev/tutorials/update-customer-data-with-storefront-api#creating-an-access-token, which should enable me to retrieve customer data and purchase information - this would enable the application to determine the correct access level for the user and their names etc. This does mean I'd need an alternative mechanism for authenticating and authorising the end user to my API which doesn't rely on passing user credentials around (it's all Https / Private network, so if that's all I can do it's not the end of the world).
It feels like I'm attempting to use Shopify in a way that it's not really designed to be used, so I'd be open to any more robust / secure suggestions anyone might have.
You are totally correct. You cannot authorize public customers of your client's Shopify store using their credentials in Shopify.
As such, you can create a user account in your App that has their customer details, but you are then walking a very fine line. If you screw up anything and expose those customer details to the world, you are liable, not your merchant buddy. With the customer info in your DB, like their email address, you could attempt to make it easier for them by asking them to simply provide their own password to your service, with the usual measures of forgotten password recovery etc.
You're not doing anything terribly complex, but you are operating with data you do not own, on behalf of a merchant subject to pretty strict privacy laws these days, meaning the full weight of the hammer could fall on you... but you probably already know that.
Thanks for the reply, I was fairly sure it wasn't going to work in the way I'd like, but good to get confirmation.
To be clear, I'm hoping to leverage Shopify accounts precisely so I don't need to store any PII and to delegate all of the account management to Shopify.
I suspect that the best way to achieve what I want is to present a login page to the user which collects their Shopify Username & password, and use this to perform a login to the shopify API using this mechanism;
I can then request user data for that user without storing this information on my side other than in ephemeral session storage. The client uses a tiered Free, Basic and Premium model for the authorisation we need which map to different SKUs it their store. I can (presumably) get which one they've purchased from the Shopify API as part of the call(s) to get customer information) This information would then form the basis of the filtering I need to do in my application, with authorization to the API being done via client credentials (since both the API and MVC app are private clients) rather than making API Calls on behalf of the user.
This isn't ideal since we loose some nice features (specifically refresh tokens), but covers what we want to do. I'm probably going to use web hooks to update / invalidate a user's current "access level" if they make a purchase after "logging in" to the MVC app.
Can you see any issues I might run in to with this approach?