使用AngularJS和Django REST Framework进行Facebook验证

前端之家收集整理的这篇文章主要介绍了使用AngularJS和Django REST Framework进行Facebook验证前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在开发一个SPA应用程序与 AngularJS使用 Django后端的服务器。我从SPA与服务器通信的方式是与 django-rest-framework.所以现在我想使用Facebook(谷歌和Twitter的认证),我阅读了很多关于这个主题,发现 OAuth.io这是在客户端上的验证SPA侧和 python-social-auth这是做同样的事,但在服务器端。

所以目前我只有客户端auth,我的应用程序连接到Facebook(与OAuth.io),并成功登录。这个过程返回access_token,然后我向我的API发出请求,它必须登录用户或通过给定令牌为此用户创建帐户,这部分不工作。所以我不知道我错了,也许因为没有一个完整的教程使用python-social-auth,所以也许我错过了一些东西或..我不知道。

所以一些代码这是我有:

在SPA端:这是与OAuth.io的连接,并且正在工作,因为我获得访问令牌。然后我必须向我的休息API发出请求。后端是’facebook’,’google’或’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');
         });
});

在我的settings.py中的服务器上我添加了社交插件到已安装的应用程序,模板上下文预处理器,一些auth后端,这是我的文件

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',)

在我的views.py的API我有以下(我发现它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

最后我在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),...

每次当我尝试做auth,OAuth.io是工作和rqest到api返回

detail: “Invalid token”

我认为我错过了在配置python-social-auth的东西,或者我做错了一切。所以我会很高兴,如果任何人有一些想法,并希望帮助:)

将以下行添加到您的ObtainAuthToken类
authentication_classes = ()

而您的错误{“detail”:“无效的令牌”}将会消失。

这里是为什么…

您的请求包含以下标题

Authorization: Token yourAccessToken

但您已在DEFAULT_AUTHENTICATION_CLASSES中定义了rest_framework.authentication.TokenAuthentication。

基于这个Django认为你想要执行令牌认证,因为你已经通过一个令牌。它失败,因为这是一个访问令牌的facebook和不存在于你的django * _token数据库,因此无效令牌错误。在你的case你所需要做的是告诉Django不要使用TokenAuthentication这个视图。

FYI

请记住,在执行ObtainAuthToken的post方法之前,您的代码执行已停止,您可能会遇到更多错误。就个人而言,当试图逐步完成你的代码,我得到的错误

'DjangoStrategy' object has no attribute 'backend'

backend = request.strategy.backend

并通过更改为解决

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

此外,你应该更新你的register_by_access_token函数,因为它不符合你引用的博客的工作代码博客作者发布了他的最新代码here.您的版本没有拉出令牌从auth标题,这是必需的,如果你想使用它与第三方如Facebook的身份验证。

猜你在找的Angularjs相关文章