Django REST social auth
=======================

|Build Status| |Coverage Status|

OAuth signin with django rest framework.

Requirements
------------

-  python (2.6, 2.7, 3.4)
-  django (1.6, 1.7, 1.8)
-  djangorestframework (3.1)

Release notes
-------------

`Here <https://github.com/st4lk/django-rest-social-auth/blob/master/RELEASE_NOTES.md>`__

Motivation
----------

To have a resource, that will do very simple thing: take the oauth code
from social provider (for example facebook) and return the authenticated
user. That's it.

I can't find such util for `django rest
framework <http://www.django-rest-framework.org/>`__. There are
packages, that take access\_token, not the code. Also, i've used to work
with awesome library
`python-social-auth <https://github.com/omab/python-social-auth>`__, so
it will be nice to use it again. In fact, most of the work is done by
this package. Current util brings a little help to integrate
djangorestframework and python-social-auth.

Quick start
-----------

1. Install this package to your python distribution:

   ::

       pip install rest-social-auth

2. Do the settings

   Install apps

   ::

       INSTALLED_APPS = (
           ...
           'social.apps.django_app.default',  # python social auth
           'rest_framework',
           'rest_framework.authtoken',  # only if you use token authentication
           'rest_social_auth',
       )

   python-social-auth settings, look
   `documentation <http://psa.matiasaguirre.net/docs/configuration/django.html>`__
   for more details

   ::

       SOCIAL_AUTH_FACEBOOK_KEY = 'your app client id'
       SOCIAL_AUTH_FACEBOOK_SECRET = 'your app client secret'
       SOCIAL_AUTH_FACEBOOK_SCOPE = ['email', ]  # optional
       SOCIAL_AUTH_FACEBOOK_PROFILE_EXTRA_PARAMS = {'locale': 'ru_RU'}  # optional


       AUTHENTICATION_BACKENDS = (
           'social.backends.facebook.FacebookOAuth2',
           # and maybe some others ...
           'django.contrib.auth.backends.ModelBackend',
       )

   Also look `optional settings <#settings>`__ avaliable.

3. Include rest social urls

   2.1 `session
   authentication <http://www.django-rest-framework.org/api-guide/authentication/#sessionauthentication>`__

   ::

       url(r'^api/login/', include('rest_social_auth.urls_session')),

   2.2 `token
   authentication <http://www.django-rest-framework.org/api-guide/authentication/#tokenauthentication>`__

   ::

       url(r'^api/login/', include('rest_social_auth.urls_token')),

4. You are ready to login users.

   3.1 session authentication

   -  POST /api/login/social/session/

      input:

      ::

          {
              "provider": "faceboook",
              "code": "AQBPBBTjbdnehj51"
          }

      output:

      ::

          {
              "username": "Alex",
              "email": "user@email.com",
              // other user data
          }

          + session id in cookies

   3.2 token authentication

   -  POST /api/login/social/token/

      input:

      ::

          {
              "provider": "faceboook",
              "code": "AQBPBBTjbdnehj51"
          }

      output:

      ::

          {
              "token": "68ded41d89f6a28da050f882998b2ea1decebbe0"
          }

   -  POST /api/login/social/token\_user/

      input:

      ::

          {
              "provider": "faceboook",
              "code": "AQBPBBTjbdnehj51"
          }

      output:

      ::

          {
              "username": "Alex",
              "email": "user@email.com",
              // other user data
              "token": "68ded41d89f6a28da050f882998b2ea1decebbe0"
          }

   User model is taken from
   ```settings.AUTH_USER_MODEL`` <https://docs.djangoproject.com/en/dev/topics/auth/customizing/#substituting-a-custom-user-model>`__.

OAuth 2.0 workflow with rest-social-auth
----------------------------------------

1. Front-end need to know follwoing params for each social provider:

   -  client\_id *# id of registered application on social service
      provider*
   -  redirect\_uri *# to this url social provider will redirect with
      code*
   -  scope=your\_scope *# for example email*
   -  response\_type=code *# same for all oauth2.0 providers*

2. Front-end redirect user to social authorize url with params from
   previous point + optional random ``state`` string.

3. User confirms.

4. Social provider redirects back to ``redirect_uri`` with param
   ``code`` and possibly ``state``, if it was given at point 2.
   Front-end better check, that state is the same.

5. Front-end now ready to login the user. To do it, send POST request
   with all params from point 4 + provider name:

   ::

       POST /api/login/social/session/

   with data (form data or json)

   ::

       provider=facebook&code=AQBPBBTjbdnehj51

   Backend will either signin the user, either signup, either return
   error.

rest-social-auth purpose
------------------------

As we can see, our backend must implement resource for signin the user
(point 5).

Django REST social auth provides means to easily implement these
resource.

List of oauth providers
-----------------------

Currently only OAuth 2.0 providers are supported. Look
`python-social-auth <https://github.com/omab/python-social-auth#user-content-auth-providers>`__
for full list. Name of provider is taken from corresponding
``backend.name`` property of particular backed class in
python-social-auth.

For example for `facebook
backend <https://github.com/omab/python-social-auth/blob/master/social/backends/facebook.py#L19>`__
we see:

::

        class FacebookOAuth2(BaseOAuth2):
            name = 'facebook'

Here are some provider names:

+-------------+-----------------+
| Provider    | provider name   |
+=============+=================+
| Facebook    | facebook        |
+-------------+-----------------+
| Google      | google-oauth2   |
+-------------+-----------------+
| Vkontakte   | vk-oauth2       |
+-------------+-----------------+
| Instagram   | instagram       |
+-------------+-----------------+
| Github      | github          |
+-------------+-----------------+
| Yandex      | yandex-oauth2   |
+-------------+-----------------+

Settings
--------

-  ``REST_SOCIAL_OAUTH_REDIRECT_URI``

   Defines redirect\_uri. This redirect must be the same in both
   authorize request (made by front-end) and access token request (made
   by back-end) to OAuth provider.

   By default is the root relative path:

   ::

       '/'

   To override the relative path (url path or url name are both
   supported):

   ::

       REST_SOCIAL_OAUTH_REDIRECT_URI = '/oauth/redirect/path/'
       # or url name
       REST_SOCIAL_OAUTH_REDIRECT_URI = 'redirect_url_name'

-  ``REST_SOCIAL_OAUTH_ABSOLUTE_REDIRECT_URI``

   Sometime project's front-end and back-end are run on different
   domains. For example frontend at 'myproject.com', and backend at
   'api.myproject.com'. To handle this, it is possible to define
   absolute redirect\_uri:

   ::

       REST_SOCIAL_OAUTH_ABSOLUTE_REDIRECT_URI = 'http://myproject.com/'

Customization
-------------

First of all, all customization avaliable by python-social-auth is also
avaliable. For example, use nice concept of
`pipeline <http://psa.matiasaguirre.net/docs/pipeline.html>`__ to do any
action you need during login/signin.

Second, you can override any method from current package. You can
specify serializer for each view or by subclassing the view.

To do it

-  define your own url:

   ::

       url(r'^api/login/social/$', MySocialView.as_view(), name='social_login'),

-  define your serializer

   ::

       from rest_framework import serializers
       from django.contrib.auth import get_user_model

       class MyUserSerializer(serializers.ModelSerializer):

           class Meta:
               model = get_user_model()
               exclude = ('password', 'user_permissions', 'groups')

-  define view

   ::

       class SocialSessionAuthView(BaseSocialAuthView):
           serializer_class_out = MyUserSerializer

Example
-------

Checkout `example
project <https://github.com/st4lk/django-rest-social-auth/tree/master/example_project>`__.

-  download it

   ::

       git clone https://github.com/st4lk/django-rest-social-auth.git

-  step in example\_project/

   ::

       cd django-rest-social-auth/example_project

-  create database (sqlite3)

   ::

       python manage.py syncdb

-  run development server

   ::

       python manage.py runserver

Example project already contains facebook app id and secret. This app is
configured to work only with restsocialexample.com domain. So, to play
with it, define in you
`hosts <http://en.wikipedia.org/wiki/Hosts_(file)>`__ file this domain
as localhost:

::

    127.0.0.1       restsocialexample.com

And visit http://restsocialexample.com:8000/

.. |Build Status| image:: https://travis-ci.org/st4lk/django-rest-social-auth.svg?branch=master
   :target: https://travis-ci.org/st4lk/django-rest-social-auth
.. |Coverage Status| image:: https://coveralls.io/repos/st4lk/django-rest-social-auth/badge.svg?branch=master
   :target: https://coveralls.io/r/st4lk/django-rest-social-auth?branch=master
