This Django package makes it easy to integrate Shopify authentication into your Django app. It shares some similaritieswith the [shopify_django_app](https://github.com/Shopify/shopify_django_app) project, but with a couple of keydifferences:

* It provides a custom Django Authentication scheme based on `AbstractBaseUser` and `RemoteUserBackend`, meaning shops will be authenticated as "users" of your Django app. This makes it easier to use common Django patterns and libraries (such as accessing the currently authenticated store as `request.user`).

* It persists users' Shopify access tokens in the database, rather than in the Session, meaning your app will be able to make API calls on behalf of a user when they're not logged in.

This project provides one package, `shopify_auth`.A demonstration Django project using this package is available [here](https://github.com/discolabs/auth_demo).

If you'd like a detailed breakdown of how to set up an app from scratch using this package, I've recorded a a shortseries of [five minute screencasts](http://gavinballard.com/shopify-app-in-15-minutes-with-django/) showing how to getan app using `django-shopify-auth` up and running in under 15 minutes.

Package Status--------------The package author (@gavinballard) is currently in "non-active maintenance" mode.I am happy to review and merge pull requests that provide a clear description ofthe problem they solve and provide a thorough test to avoid any regressions, butas I don't use Django in my day-to-day Shopify development any more (the lastversion I used with much regularity was Django 1.9) I am not actively working onthe code.

If you're using this package on a regular basis and feel you'd be a good fit totake over active development, please [contact me](https://twitter.com/gavinballard).

Requirements------------Tests are run against Django v1.8, v1.10, and v1.11. This package may work forother Django versions but it's not guaranteed.

As with the original `shopify_django_app` package, you'll need a [Shopify partner account](http://shopify.com/partners)and to have created an app in order to get an API key and secret.

Package Installation and Setup------------------------------There are a few moving parts to set up, but hopefully the following instructions will make things straightforward.

We're assuming in this setup that you're using a standard Django project layout (the sort that's created with the`django-admin.py startproject` command). We're also assuming that our project is called `auth_demo` and that the primaryDjango app inside our project is going to be called `auth_app`.

If you ever get lost or aren't really sure what to do, you can refer to the [demo app](https://github.com/discolabs/auth_demo).

### 1. Install packageInstallation is super easy via `pip`:

```shell> pip install django-shopify-auth```

Once you have the package installed, add `shopify_auth` to your `INSTALLED_APPS`.

This backend requires that the user model for your app (specified by `AUTH_USER_MODEL` in your `settings.py`) inheritsfrom `shopify_auth.models.AbstractShopUser`. To do this, just add something like this to the `models.py` for yourDjango app:

# Set the login redirect URL to the "home" page for your app (where to go after logging on).LOGIN_REDIRECT_URL = '/'

# Set secure proxy header to allow proper detection of secure URLs behind a proxy.# This ensures that correct 'https' URLs are generated when our Django app is running behind a proxy like nginx, or is# being tunneled (by ngrok, for example).SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')```

Note that in the example above, the application API key and API secret are pulled from environment settings, which is abest practice for Django apps that helps avoid the accidental check-in of sensitive information to source files.

Set `SHOPIFY_APP_IS_EMBEDDED` to `True` if your app has been configured as an Embedded app (you choose this option atthe time of app creation). Setting this will make the app provide a Javascript-based redirect that breaks out of anembedded app's `<iframe>` during the authentication flow as per [the Shopify documentation](http://docs.shopify.com/embedded-app-sdk).If `SHOPIFY_APP_IS_EMBEDDED` is `False`, the normal authentication flow for non-Embedded apps will be used.

Setting `SHOPIFY_APP_DEV_MODE` to `True` allows you to test your apps locally by skipping the external OAuth phase foryour app. As it means you can log into your app as any store, you should obviously ***never*** set this to `True` inproduction.

Now that all of the settings are configured, you can run `migrate` to set up the database for your new user model:

### 5. Create application viewsNow that you've gotten the configuration out of the way, you can start building your application.

All views inside your application should be decorated with `@login_required`.This decorator will check that a user has authenticated through the Shopify OAuth flow.If they haven't, they'll be redirected to the login screen.

### 6. Using the Embedded App SDKIf you're using the Embedded App SDK, be aware that the HTML your views return must contained some Javascript in the`<head>` to properly frame your app within the Shopify Admin.

Generally, all pages you'd like embedded in the Shopify Admin should contain something like this in `<head>`:

Recent versions of Django's `startproject` add `django.middleware.clickjacking.XFrameOptionsMiddleware` to the`MIDDLEWARE_CLASSES` list in `settings.py`. This prevents pages being loading in an `<iframe>`, meaning your app pageswill not be displayed in the Shopify admin.

To resolve this issue, you should either remove `XFrameOptionsMiddleware` from your `MIDDLEWARE_CLASSES`, or ensure thatall of your app views make use of the `@xframe_options_exempt` decorator.

### 7. Making Shopify API callsTo make Shopify API calls on behalf of a user, we can use the user's `session` property inside a `with` statement:

```pythondef view(request, *args, **kwargs):

# Get a list of the user's products. with request.user.session: products = shopify.Product.find()

# ... remaining view code ...```

Behind the scenes, using `with request.user.session` sets up a temporary Shopify API session using the OAuth token weobtained for that specific user during authentication.

All code wrapped within the `with` statement is executed in the context of the specified user. You should always wrapcalls to the Shopify API using this pattern.

Partner Application Setup-------------------------In addition to getting the package up and running in your local Django project, you'll need to configure yourapplication via the Shopify Partner dashboard. The first part of my brief [screencast series](http://gavinballard.com/shopify-app-in-15-minutes-with-django/)walks you through the setup of a Shopify Partner application.

An ***important omission*** from the screencast series is that Shopify now requires applications to provide a list ofauthorized "Redirection URLs" from the partner dashboard for enhanced security (this wasn't a required setting at thetime of recording the screencasts).

To avoid getting an OAuth error while customers try to install your application, make sure your application's settingsinclude the absolute URL to `/login/finalize/` (including the trailing slash) in their whitelisted URLs. For example,if your application resides at `https://myapp.example.com`, then you should include`https://myapp.example.com/login/finalize/` in the "Redirection URL" section of your application settings.

Questions or Problems?----------------------

Browse through the code for the demo app:<https://github.com/discolabs/auth_demo>

Read up on the possible API calls:<http://api.shopify.com>

Learn how to use the `shopify_python_api` library:<http://wiki.shopify.com/Using_the_shopify_python_api>