所以目前我只有客户端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的东西,或者我做错了一切。所以我会很高兴,如果任何人有一些想法,并希望帮助:)
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的身份验证。