framework auth facebook angularjs django-rest-framework python-social-auth

auth - Autenticación de Facebook con AngularJS y Django REST Framework



django rest framework facebook login (3)

Agregue la siguiente línea a su clase ObtainAuthToken

authentication_classes = ()

y su error {"detalle": "token inválido"} desaparecerá.

Este es el por qué...

Su solicitud contiene el siguiente encabezado

Authorization: Token yourAccessToken

sin embargo, ha definido rest_framework.authentication.TokenAuthentication en DEFAULT_AUTHENTICATION_CLASSES.

En función de esto, Django cree que desea realizar la autenticación de token cuando haya pasado un token. Falla porque este es un token de acceso para Facebook y no existe en su base de datos django * _token, de ahí el error del token no válido. En su caso, todo lo que necesita hacer es decirle a Django que no use TokenAuthentication para esta vista.

FYI

Tenga en cuenta que puede encontrar más errores ya que la ejecución del código se detuvo antes de que se ejecutara el método de publicación de ObtainAuthToken. Personalmente cuando trato de pasar por su código, recibí el error

''DjangoStrategy'' object has no attribute ''backend''

en

backend = request.strategy.backend

y lo resolvió cambiando a

uri = '''' strategy = load_strategy(request) backend = load_backend(strategy, backend, uri)

Además, debe actualizar su función register_by_access_token ya que no se alinea con el código de trabajo del blog al que hizo referencia. El autor del blog publicó su último código here . Su versión no extrae el token del encabezado de autenticación, que es obligatorio si desea usarlo para autenticarse con un tercero como Facebook.

Estoy desarrollando una aplicación SPA con AngularJS que utiliza el back-end de Django para el servidor. La forma en que me comunico con el servidor desde el SPA es con django-rest-framework . Así que ahora quiero hacer autenticación con Facebook (también en google y twitter) y leo mucho sobre este tema y encontré OAuth.io que está haciendo la autenticación en el lado SPA del cliente y python-social-auth que está haciendo lo mismo pero en el lado del servidor.

Por lo tanto, actualmente solo tengo la autenticación del cliente, mi aplicación se conecta a Facebook (con OAuth.io) y se registra con éxito. Este proceso está devolviendo access_token y luego estoy haciendo una solicitud a mi API que tiene que iniciar sesión en este usuario o crear una cuenta para este usuario con un token dado y esta parte no está funcionando. Así que no estoy seguro de dónde estoy equivocado, tal vez porque no hay un tutorial completo sobre el uso de Python-social-auth, así que tal vez me esté perdiendo algo o ... No sé ...

Entonces algún código de esto es lo que tengo:

En el lado de SPA: Esta es la conexión con OAuth.io y está funcionando porque recibo el token de acceso. Entonces tengo que hacer una solicitud a mi API de descanso. backend es ''facebook'', ''google'' o ''twitter''

OAuth.initialize(''my-auth-code-for-oauthio''); OAuth.popup(backend, function(error, result) { //handle error with error //use result.access_token in your API request var token = ''Token '' + result.access_token; var loginPromise = $http({ method:''POST'', url: ''api-token/login/'' + backend + ''/'', headers: {''Authorization'': token}}); loginPromise.success(function () { console.log(''Succeess''); }); loginPromise.error(function (result) { console.log(''error''); }); });

En el servidor de mi settings.py he agregado el complemento social a las aplicaciones instaladas, los preprocesadores de contexto de la plantilla, algunos back-end de autenticación y ese es mi archivo:

INSTALLED_APPS = ( ''django.contrib.auth'', ''django.contrib.contenttypes'', ''django.contrib.sessions'', ..., ''rest_framework'', ''rest_framework.authtoken'', ''api'', ''social.apps.django_app.default'', ''social'' ) TEMPLATE_CONTEXT_PROCESSORS = ("django.contrib.auth.context_processors.auth", "django.core.context_processors.debug", "django.core.context_processors.i18n", "django.core.context_processors.media", "django.core.context_processors.static", "django.core.context_processors.request", "django.contrib.messages.context_processors.messages", ''social.apps.django_app.context_processors.backends'', ''social.apps.django_app.context_processors.login_redirect'',) REST_FRAMEWORK = { ''DEFAULT_AUTHENTICATION_CLASSES'': ( ''rest_framework.authentication.TokenAuthentication'', ) } SOCIAL_AUTH_FACEBOOK_KEY = ''key'' SOCIAL_AUTH_FACEBOOK_SECRET = ''secret'' SOCIAL_AUTH_FACEBOOK_SCOPE = [''email''] AUTHENTICATION_BACKENDS = ( ''social.backends.open_id.OpenIdAuth'', ''social.backends.facebook.FacebookOAuth2'', ''social.backends.facebook.FacebookAppOAuth'', ''social.backends.google.GoogleOpenId'', ''social.backends.google.GoogleOAuth2'', ''social.backends.google.GoogleOAuth'', ''social.backends.twitter.TwitterOAuth'', ''django.contrib.auth.backends.ModelBackend'', )

En mi views.py de la API tengo lo siguiente (lo encontré here ):

from django.contrib.auth.models import User, Group from rest_framework import viewsets, generics from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import authentication, permissions, parsers, renderers from rest_framework.authtoken.serializers import AuthTokenSerializer from rest_framework.decorators import api_view, throttle_classes from social.apps.django_app.utils import strategy from rest_framework.permissions import IsAuthenticated, IsAuthenticatedOrReadOnly from django.contrib.auth import get_user_model from django.db.models.signals import post_save from django.dispatch import receiver from rest_framework.authtoken.models import Token class ObtainAuthToken(APIView): throttle_classes = () permission_classes = () parser_classes = (parsers.FormParser, parsers.MultiPartParser, parsers.JSONParser,) renderer_classes = (renderers.JSONRenderer,) serializer_class = AuthTokenSerializer model = Token # Accept backend as a parameter and ''auth'' for a login / pass def post(self, request, backend): serializer = self.serializer_class(data=request.DATA) if backend == ''auth'': if serializer.is_valid(): token, created = Token.objects.get_or_create(user=serializer.object[''user'']) return Response({''token'': token.key}) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) else: # Here we call PSA to authenticate like we would if we used PSA on server side. user = register_by_access_token(request, backend) # If user is active we get or create the REST token and send it back with user data if user and user.is_active: token, created = Token.objects.get_or_create(user=user) return Response({''id'': user.id , ''name'': user.username, ''userRole'': ''user'',''token'': token.key}) @strategy() def register_by_access_token(request, backend): backend = request.strategy.backend user = request.user user = backend._do_auth( access_token=request.GET.get(''access_token''), user=user.is_authenticated() and user or None ) return user

Y finalmente tengo estas rutas en urls.py:

... url(r''^api-auth/'', include(''rest_framework.urls'', namespace=''rest_framework'')), url(r''^api-token-auth/'', ''rest_framework.authtoken.views.obtain_auth_token''), url(r''^api-token/login/(?P<backend>[^/]+)/$'', views.ObtainAuthToken.as_view()), url(r''^register/(?P<backend>[^/]+)/'', views.register_by_access_token), ...

Cada vez que intento hacer auth, OAuth.io está funcionando y regresa el rqest to api

detalle: "token inválido"

Creo que me perdí algo en la configuración de python-social-auth o estoy haciendo todo mal. Así que me alegrará si alguien tiene algunas ideas y quiere ayudar :)


Estoy usando herramientas como tú, pero proporciono mi login / register / .... con el paquete django-allauth , y luego uso django-rest-auth para el manejo de la API.

Solo necesita seguir las instrucciones de instalación y luego usarlas para sus API de descanso.

Agregar allauth y rest-auth a su INSTALLED_APPS:

INSTALLED_APPS = ( ..., ''rest_framework'', ''rest_framework.authtoken'', ''rest_auth'' ..., ''allauth'', ''allauth.account'', ''rest_auth.registration'', ..., ''allauth.socialaccount'', ''allauth.socialaccount.providers.facebook'', )

A continuación, agregue sus URL personalizados:

urlpatterns = patterns('''', ..., (r''^auth/'', include(''rest_auth.urls'')), (r''^auth/registration/'', include(''rest_auth.registration.urls'')) )

Finalmente, agregue esta línea:

TEMPLATE_CONTEXT_PROCESSORS = ( ..., ''allauth.account.context_processors.account'', ''allauth.socialaccount.context_processors.socialaccount'', ... )

Estos dos paquetes funcionan como un amuleto, y no necesita preocuparse por ningún tipo de registro de inicio de sesión, porque el paquete allauth maneja el inicio de sesión del modelo django y el inicio de sesión de oAuth.

Espero que ayude


Sí. Resuelto La configuración no es correcta y debe agregar permisos.

REST_FRAMEWORK = { # Use hyperlinked styles by default. # Only used if the `serializer_class` attribute is not set on a view. ''DEFAULT_MODEL_SERIALIZER_CLASS'': ''rest_framework.serializers.HyperlinkedModelSerializer'', # Use Django''s standard `django.contrib.auth` permissions, # or allow read-only access for unauthenticated users. ''DEFAULT_PERMISSION_CLASSES'': [ ''rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'' ] }

y alguna información sobre la tubería:

SOCIAL_AUTH_PIPELINE = ( ''social.pipeline.social_auth.social_details'', ''social.pipeline.social_auth.social_uid'', ''social.pipeline.social_auth.auth_allowed'', ''social.pipeline.social_auth.social_user'', ''social.pipeline.user.get_username'', ''social.pipeline.social_auth.associate_by_email'', ''social.pipeline.user.create_user'', ''social.pipeline.social_auth.associate_user'', ''social.pipeline.social_auth.load_extra_data'', ''social.pipeline.user.user_details'' )