Django rest framework resources for social auth
Project description
Django REST social auth
OAuth signin with django rest framework.
Requirements
- python (2.7, 3.5, 3.6, 3.7)
- django (1.11, 2.0, 2.1)
- djangorestframework (>=3.1, <4.0)
- social-auth-core (>=3.0, <4.0)
- social-auth-app-django (>=3.1, <4.0)
- [optional] djangorestframework-simplejwt (>=4.0.0)
- [optional] django-rest-knox (>=3.2.0)
Release notes
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. There are packages (for example django-rest-auth), that take access_token, not the code. Also, i've used to work with awesome library python-social-auth, so it will be nice to use it again (now it is split into social-core and social-app-django). In fact, most of the work is done by this package. Current util brings a little help to integrate django-rest-framework and python-social-auth.
Quick start
-
Install this package to your python distribution:
pip install rest-social-auth
-
Do the settings
Install apps
INSTALLED_APPS = ( ... 'rest_framework', 'rest_framework.authtoken', # only if you use token authentication 'social_django', # django social auth 'rest_social_auth', # this package 'knox', # Only if you use django-rest-knox )
social auth settings, look documentation 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_core.backends.facebook.FacebookOAuth2', # and maybe some others ... 'django.contrib.auth.backends.ModelBackend', )
Also look optional settings avaliable.
-
Make sure everything is up do date
python manage.py migrate
-
Include rest social urls (choose at least one)
url(r'^api/login/', include('rest_social_auth.urls_session')),
url(r'^api/login/', include('rest_social_auth.urls_token')),
url(r'^api/login/', include('rest_social_auth.urls_jwt_pair')),
or / and
url(r'^api/login/', include('rest_social_auth.urls_jwt_sliding')),
url(r'^api/login/', include('rest_social_auth.urls_knox')),
-
You are ready to login users
Following examples are for OAuth 2.0.
5.1 session authentication
-
POST /api/login/social/session/
input:
{ "provider": "facebook", "code": "AQBPBBTjbdnehj51" }
output:
{ "username": "Alex", "email": "user@email.com", // other user data } + session id in cookies
5.2 token authentication
-
POST /api/login/social/token/
input:
{ "provider": "facebook", "code": "AQBPBBTjbdnehj51" }
output:
{ "token": "68ded41d89f6a28da050f882998b2ea1decebbe0" }
-
POST /api/login/social/token_user/
input:
{ "provider": "facebook", "code": "AQBPBBTjbdnehj51" }
output:
{ "username": "Alex", "email": "user@email.com", // other user data "token": "68ded41d89f6a28da050f882998b2ea1decebbe0" }
5.3 jwt authentication
-
POST /api/login/social/jwt-pair/
-
POST /api/login/social/jwt-pair-user/
Similar to token authentication, but token is JSON Web Token.
See JWT.io for details.
To use it, django-rest-framework-simplejwt must be installed.
For
jwt-pair
, the response will include additional "refresh" token:{ "token": "...", "refresh": "..." }
Or sliding JWT token:
-
POST /api/login/social/jwt-sliding/
-
POST /api/login/social/jwt-sliding-user/
Check docs of simplejwt for pair/sliding token difference.
5.4 knox authentication
-
POST /api/login/social/knox/
-
POST /api/login/social/knox_user/
Similar to jwt/token authentication, but token is a Django Rest Knox Token.
To use it, django-rest-knox must be installed.
User model is taken from
settings.AUTH_USER_MODEL
.At input there is also non-required field
redirect_uri
. If given, server will use this redirect uri in requests, instead of uri got from settings. This redirect_uri must be equal in front-end request and in back-end request. Back-end will not do any redirect in fact.It is also possible to specify provider in url, not in request body. Just append it to the url:
POST /api/login/social/session/facebook/
Don't need to specify it in body now:
{ "code": "AQBPBBTjbdnehj51" }
-
OAuth 2.0 workflow with rest-social-auth
-
Front-end need to know following params for each social provider:
- client_id # only in case of OAuth 2.0, 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
-
Front-end redirect user to social authorize url with params from previous point.
-
User confirms.
-
Social provider redirects back to
redirect_uri
with paramcode
. -
Front-end now ready to login the user. To do it, send POST request with provider name and code:
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.
Sometimes it is more suitable to specify provider in url, not in request body. It is possible, rest-social-auth will understand that. Following request is the same as above:
POST /api/login/social/session/facebook/
with data (form data or json)
code=AQBPBBTjbdnehj51
OAuth 1.0a workflow with rest-social-auth
-
Front-end needs to make a POST request to your backend with the provider name ONLY:
POST /api/login/social/
with data (form data or json):
provider=twitter
Or specify provider in url, in that case data will be empty:
POST /api/login/social/twitter
-
The backend will return a short-lived
oauth_token
request token in the response. This can be used by the front-end to perform authentication with the provider. -
User confirms. In the case of Twitter, they will then return the following data to your front-end:
{ "redirect_state": "...bHrz2x0wy43", "oauth_token" : "...AAAAAAAhD5u", "oauth_verifier": "...wDBdTR7CYdR" }
-
Front-end now ready to login the user. To do it, send POST request again with provider name and the
oauth_token
andoauth_verifier
you got from the provider:POST /api/login/social/
with data (form data or json)
provider=twitter&oauth_token=AQBPBBTjbdnehj51&oauth_verifier=wDBdTR7CYdR
Backend will either signin the user, or signup, or return an error. Same as in OAuth 2.0, you can specify provider in url, not in body:
POST /api/login/social/twitter
This flow is the same as described in satellizer. This angularjs module is used in example project.
Note
If you use token (or jwt) authentication and OAuth 1.0, then you still need 'django.contrib.sessions' app (it is not required for OAuth 2.0 and token authentication). This is because python-social-auth will store some data in session between requests to OAuth 1.0 provider.
rest-social-auth purpose
As we can see, our backend must implement resource for signin the user.
Django REST social auth provides means to easily implement such resource.
List of oauth providers
OAuth 1.0 and OAuth 2.0 providers are supported.
Look python-social-auth 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 we see:
class FacebookOAuth2(BaseOAuth2):
name = 'facebook'
Here are some provider names:
Provider | provider name |
---|---|
google-oauth2 | |
Vkontakte | vk-oauth2 |
Github | github |
Yandex | yandex-oauth2 |
Others | ... |
Settings
-
REST_SOCIAL_OAUTH_REDIRECT_URI
Default:
'/'
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.
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'
Note, in case of url name, backend name will be provided to url resolver as argument.
-
REST_SOCIAL_DOMAIN_FROM_ORIGIN
Default:
True
Sometimes front-end and back-end are run on different domains. For example frontend at 'myproject.com', and backend at 'api.myproject.com'.
If True, domain will be taken from request origin, if origin is defined. So in current example domain will be 'myproject.com', not 'api.myproject.com'. Next, this domain will be joined with path from
REST_SOCIAL_OAUTH_REDIRECT_URI
settings.To be clear, suppose we have following settings (defaults):
REST_SOCIAL_OAUTH_REDIRECT_URI = '/' REST_SOCIAL_DOMAIN_FROM_ORIGIN = True
Front-end is running on domain 'myproject.com', back-end - on 'api.myproject.com'. Back-end will use following redirect_uri:
myproject.com/
And with following settings:
REST_SOCIAL_OAUTH_REDIRECT_URI = '/' REST_SOCIAL_DOMAIN_FROM_ORIGIN = False
redirect_uri will be:
api.myproject.com/
Also look at django-cors-headers if such architecture is your case.
-
REST_SOCIAL_OAUTH_ABSOLUTE_REDIRECT_URI
Default:
None
Full redirect uri (domain and path) can be hardcoded
REST_SOCIAL_OAUTH_ABSOLUTE_REDIRECT_URI = 'http://myproject.com/'
This settings has higher priority than
REST_SOCIAL_OAUTH_REDIRECT_URI
andREST_SOCIAL_DOMAIN_FROM_ORIGIN
. I.e. if this settings is defined, other will be ignored. Butredirect_uri
param from request has higher priority than any setting. -
REST_SOCIAL_LOG_AUTH_EXCEPTIONS
Default:
True
When
False
will not log social auth authentication exceptions.
Customization
First of all, customization provided by python-social-auth is also avaliable. For example, use nice mechanism of pipeline to do any action you need during login/signin.
Second, you can override any method from current package. Specify serializer for each view 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
from rest_social_auth.views import SocialSessionAuthView from .serializers import MyUserSerializer class MySocialView(SocialSessionAuthView): serializer_class = MyUserSerializer
Check the code of the lib, there is not much of it.
Example
There is an example project.
-
clone repo
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)
PYTHONPATH='../' python manage.py migrate
Note: You can avoid
PYTHONPATH='../'
if you install the package locally:pip install rest-social-auth
orpython setup.py install
. But to my mind the PYTHONPATH prefix is more useful. No need to install anything and code of rest-social-auth will be always up-to-date, even if you change source code. -
run development server
PYTHONPATH='../' python manage.py runserver
Example project already contains facebook, google and twitter app ids and secrets. These apps are configured to work only with http://127.0.0.1:8000/ domain. Google and Facebook providers support http://localhost:8000/ as well. But Twitter only support 127.0.0.1. So, to play with it, visit http://127.0.0.1:8000/
Example project uses satellizer angularjs module.
Contributors
- Alexey Evseev, st4lk
- James Keys, skolsuper
- Aaron Abbott, aabmass
- Grigorii Eremeev, Budulianin
- shubham, shubh3794
- Deshraj Yadav, DESHRAJ
- georgewhewell, georgewhewell
- Ahmed Sa3d, zee93
- Olle Vidner, ovidner
- MounirMesselmeni, MounirMesselmeni
- Tuomas Virtanen, katajakasa
- Jeremy Storer, storerjeremy
rest_social_auth release notes
master
v2.1.0
- Use djangorestframework-simplejwt for JWT implementation
- Deprecate djangorestframework-jwt
- Add python3.7 support
Issues: #74
v2.0.2
- Make social-auth-core >=3.0 as mandatory dependency
v2.0.1
- Minor update of pypi deployment process
v2.0.0
- Update social-auth-core dependency to at least 3.0.0
Issues: #73
v1.5.0
- Update minimal required version of social-auth-app-django to 3.1.0
- Minor updates in readme
- Add Django 2.1 support
- Drop Django 1.10 support
- Drop Python 3.4 support
Issues: #70
v1.4.0
- Add django-rest-knox support
v1.3.1
- Fix Django 2.0 support
v1.3.0
- Add Django 2.0 support
- Drop Django 1.8, 1.9 support
Issues: #58
v1.2.0
- Add Python 3.6 and Django 1.11 support
Issues #54
v1.1.0
- Update docs
- Add new setting
REST_SOCIAL_LOG_AUTH_EXCEPTIONS
Issues #42
v1.0.0
- Add Django 1.10 support
- Drop Django 1.7 support
- Add social-auth-core, social-auth-app-django dependencies
- Drop python-social-auth dependency
Issues: #33, #35, #37, #38
v0.5.0
- Handle HttpResponses returned by the pipeline
Issues: #28
v0.4.4
- Log exceptions from python-social-auth
- Don't use find_packages from setuptools
Issues: #22, #25
v0.4.3
- Fix queryset assert error
- minor typo fixes
Issues: #20
v0.4.2
- Remove django.conf.urls.patterns from code
- Exclude modifing immutable data
- refactor tests
- minor typo fixes
Issues: #11, #17, #14
v0.4.1
- Fix requirements.txt: allow django==1.9
v0.4.0
- Add JSON Web Tokens using djangorestframework-jwt
- Add Python 3.5 and Django 1.9 support
Issues: #6
v0.3.1
- Explicitly set token authentication for token views
v0.3.0
- Add support for Oauth1
- Add ability to override request parsing
- Allow to specify provider in url
- Drop Python 2.6 and Django 1.6 support
Issues: #2, #3, #5
v0.2.0
- Get domain from HTTP Origin
- Add example of Google OAuth2.0
- Add manual redirect uri (front-end can specify it)
- Use GenericAPIView instead of APIView
- Main serializer is output serializer, not input
- Update docs
- Minor code fixes
v0.1.0
First version in pypi
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for rest_social_auth-2.1.0-py2.py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 89034b02e11d82f8ebd71dda3073340c35c135880f3f4e02d1d676737decd0d2 |
|
MD5 | d119a41c1915b5eb7381b0a4b79c692c |
|
BLAKE2b-256 | ea21346b93b9705dfd3b49b88ebffb13f4abec7fba07e5caee923a1f328433df |