-
-
Notifications
You must be signed in to change notification settings - Fork 313
Authentication and authorization
ShopifySharp should work out of the box with your private Shopify application, all you need to do is replace the shopAccessToken
with your private app's password when initializing a ShopifyService:
var service = new ProductService(myShopifyUrl, privateAppPassword)
If you just need an access token for a private Shopify app, or for running the tests in this library, refer to the Tests section below.
NOTICE: If you're using ASP.NET MVC5 (or any version that isn't AspNet Core) you'll have compilation errors when trying to pass Request.QueryString
or Request.Headers
to the authorization methods described below. See this issue for a workaround.
This is a convenience method that validates whether a given URL is a valid Shopify API domain (the Shopify API is hosted on each individual shop rather than at once central URL). It's great for ensuring
you don't redirect a user to an incorrect URL when you need them to authorize your app installation, and is
ideally used in conjunction with AuthorizationService.BuildAuthorizationUrl
.
ShopifySharp will call the given URL and check for an X-ShopId
header in the response. That header is present on all Shopify shops and it's existence signals that the URL is indeed a Shopify URL.
Note, however, that this feature is undocumented by Shopify and may break at any time. Use at your own discretion. In addition, it's possible for a malicious site to fake the X-ShopId
header which would make this method return true
.
string urlFromUser = "https://example.myshopify.com";
bool isValidDomain = await AuthorizationService.IsValidShopDomainAsync(urlFromUser).
Redirect your users to this authorization URL, where they'll be prompted to install your app to their Shopify store.
//This is the user's store URL.
string usersMyShopifyUrl = "https://example.myshopify.com";
// A URL to redirect the user to after they've confirmed app installation.
// This URL is required, and must be listed in your app's settings in your Shopify app dashboard.
// It's case-sensitive too!
string redirectUrl = "https://example.com/my/redirect/url";
//An array of the Shopify access scopes your application needs to run.
var scopes = new List<AuthorizationScope>()
{
AuthorizationScope.ReadCustomers,
AuthorizationScope.WriteCustomers
};
//Or, use an array of string permissions
var scopes = new List<string>()
{
"read_customers",
"write_customers"
}
//You can find your API key over at https://shopify.dev/tutorials/authenticate-a-private-app-with-shopify-admin
string shopifyApiKey = "";
//All AuthorizationService methods are static.
Uri authUrl = AuthorizationService.BuildAuthorizationUrl(scopes, usersMyShopifyUrl, shopifyApiKey, redirectUrl);
Once you've sent a user to the authorization URL and they've confirmed your app installation, they'll be redirected back to your application at either the default app URL, or the redirect URL you passed in when building the authorization URL.
The access token you receive after authorizing should be stored in your database. You'll need it to access the shop's resources (e.g. orders, customers, fulfillments, etc.)
//The querystring will have several parameters you need for authorization.
string code = Request.QueryString["code"];
string myShopifyUrl = Request.QueryString["shop"];
string accessToken = await AuthorizationService.Authorize(code, myShopifyUrl, shopifyApiKey, shopifySecretKey);
Any (non-webhook, non-proxy-page) request coming from Shopify will have a querystring parameter called 'hmac' that you can use to verify that the request is authentic. This signature is a hash of all querystring parameters and your app's secret key.
Pass the entire querystring to AuthorizationService
to verify the request.
var qs = Request.QueryString;
if(AuthorizationService.IsAuthenticRequest(qs, shopifySecretKey))
{
//Request is authentic.
}
else
{
//Request is not authentic and should not be acted on.
}
Nearly identical to authenticating normal requests, a proxy page request only differs in the way the HMAC is generated. All proxy page requests coming from Shopify will have a querystring parameter named hmac
that you can use to verify the request. This signature is a hash of all querystring parameters and your app's secret key.
var qs = Request.QueryString;
if(AuthorizationService.IsAuthenticProxyRequest(qs, shopifySecretKey))
{
//Request is authentic.
}
else
{
//Request is not authentic and should not be acted on.
}
Any webhook request coming from Shopify will have a header called X-Shopify-Hmac-SHA256
that you can use
to verify that the webhook is authentic. The header is a hash of the entire request body and your app's
secret key.
Pass the entire header collection and the request's input stream to AuthorizationService
to verify
the request.
NameValueCollection requestHeaders = Request.Headers;
Stream inputStream = Request.InputStream;
if(AuthorizationService.IsAuthenticWebhook(requestHeaders, inputStream, shopifySecretKey))
{
//Webhook is authentic.
}
else
{
//Webhook is not authentic and should not be acted on.
}
You can also pass in the request body as a string, rather than using the input stream. However, the request body string needs to be identical to the way it was sent from Shopify. If it has been modified the verification will fail -- even if just one space is in the wrong place.
NameValueCollection requestHeaders = Request.Headers;
string requestBody = null;
//Reset the input stream. MVC controllers often read the stream to determine which parameters to pass to an action.
Request.InputStream.Position = 0;
//Read the stream into a string
using(StreamReader reader = new StreamReader(Request.InputStream))
{
requestBody = await reader.ReadToEndAsync();
}
if(AuthorizationService.IsAuthenticWebhook(requestHeaders, requestBody, shopifySecretKey))
{
//Webhook is authentic.
}
else
{
//Webhook is not authentic and should not be acted on.
}