Facebook Auth with AngularJS 및 장고 REST 프레임워크
Angular를 사용하여 SPA 어플리케이션을 개발 중입니다.서버에 대해 Django 백엔드를 사용하는 JS.SPA에서 서버와 통신하는 방법은 django-rest-framework입니다.facebook(google과 twitter도)을 사용하여 인증을 하고 싶습니다.이 토픽을 많이 읽었는데, 클라이언트 SPA 측에서 자동 인증을 하고 있는 OAuth.io과 서버 측에서 인증을 하고 있는 python-social-auth를 발견했습니다.
그래서 현재 클라이언트 인증만 가지고 있고, 앱은 facebook(OAuth.io)에 접속하여 정상적으로 로그인하고 있습니다.이 프로세스는 access_token을 반환하고 API에 요청을 합니다.API는 이 사용자를 로그인하거나 지정된 토큰으로 이 사용자의 계정을 생성해야 하며 이 부분은 작동하지 않습니다.python-social-auth 사용에 대한 완전한 튜토리얼이 없기 때문에 제가 뭔가 놓쳤거나..나도 몰라..
그래서 내가 가지고 있는 몇 가지 암호:
SPA 측:이것은 OAuth.io과의 접속으로, 액세스 토큰을 취득하고 있기 때문에 동작하고 있습니다.그러면 rest API에 요청을 해야 합니다. 백엔드는 '페이스북', '구글', '트위터'입니다.
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의 서버에서 설치된 앱, 템플릿 컨텍스트 프리프로세서, 일부 인증 백엔드에 소셜 플러그인을 추가했습니다.이것이 내 파일입니다.
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',
)
API의 views.py에는 다음과 같은 정보가 있습니다(여기서 찾았습니다).
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
마지막으로 URL에 루트가 있습니다.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),
...
인증을 시도할 때마다 OAuth.io이 작동하고 api에 대한 rqest가 반환됩니다.
상세: "잘못된 토큰"
python-social-auth 설정에서 누락되었거나 모든 것을 잘못하고 있는 것 같습니다.그래서 아이디어나 도움이 되고 싶은 사람이 있으면 좋겠습니다.
다음 행을 GetAuthToken 클래스에 추가합니다.
authentication_classes = ()
오류 {"detail": "Invalid token"}이(가) 사라집니다.
여기 그 이유가 있다...
요청에 다음 헤더가 포함되어 있습니다.
Authorization: Token yourAccessToken
rest_displays는 정의되어 있습니다.인증이 필요합니다.DEFAULT_AUTHENTICATION_CLASSES 토큰 인증
이 Django를 기반으로 토큰을 전달한 경우 토큰 인증을 수행하려고 합니다.facebook용 액세스 토큰으로 django *_token 데이터베이스에 존재하지 않기 때문에 실패합니다.따라서 유효하지 않은 토큰 오류입니다.이 경우 이 뷰에 TokenAuthentication을 사용하지 않도록 Django에게 지시하기만 하면 됩니다.
참고:
GetAuthToken 포스트 메서드가 실행되기 전에 코드 실행이 중지되었기 때문에 추가 오류가 발생할 수 있습니다.개인적으로 당신의 코드를 확인하려고 할 때 오류가 발생했습니다.
'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 함수는 참조한 블로그의 작업 코드와 일치하지 않으므로 갱신해야 합니다.블로그 작성자가 최신 코드를 여기에 올렸습니다.사용하시는 버전에서는 인증 헤더에서 토큰을 꺼내지 않습니다.이것은, Facebook등의 서드 파티의 인증에 필요한 토큰입니다.
네, 해결됐습니다.설정이 올바르지 않으므로 권한을 추가해야 합니다.
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'
]
}
파이프라인에 대한 정보:
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'
)
저도 당신처럼 툴을 사용하고 있습니다만, 로그인/등록/...을 패키지와 함께 제공하고 API 처리에 사용합니다.
인스톨 순서에 따라서, 그것들을 나머지 API에 사용할 필요가 있습니다.
" " " allauth
★★★★★★★★★★★★★★★★★」rest-auth
합니다. 용 apps apps apps apps:
INSTALLED_APPS = (
...,
'rest_framework',
'rest_framework.authtoken',
'rest_auth'
...,
'allauth',
'allauth.account',
'rest_auth.registration',
...,
'allauth.socialaccount',
'allauth.socialaccount.providers.facebook',
)
다음으로 커스텀 URL을 추가합니다.
urlpatterns = patterns('',
...,
(r'^auth/', include('rest_auth.urls')),
(r'^auth/registration/', include('rest_auth.registration.urls'))
)
마지막으로 다음 행을 추가합니다.
TEMPLATE_CONTEXT_PROCESSORS = (
...,
'allauth.account.context_processors.account',
'allauth.socialaccount.context_processors.socialaccount',
...
)
또, 타입의 registration에 가 없습니다은, 「2」의 「로그인.레지스트레이션」의 「로그인.레지스트레이션」이기 때문입니다.allauth
loginpackage의 django를 모두 합니다.
도움이 되었으면 좋겠다
언급URL : https://stackoverflow.com/questions/20786327/facebook-auth-with-angularjs-and-django-rest-framework
'prosource' 카테고리의 다른 글
TypeScript에서 React Stateless 기능 구성 요소를 사용하는 방법 (0) | 2023.02.12 |
---|---|
Laravel angularjs 요청::ajax()는 항상 false입니다. (0) | 2023.02.08 |
EC2의 WordPress에서 플러그인을 설치하려면 FTP 자격 증명이 필요함 (0) | 2023.02.08 |
Jackson - Java 목록을 json 배열에 쓰는 가장 좋은 방법 (0) | 2023.02.08 |
WordPress에서 세션 만료 시간을 변경하는 방법 (0) | 2023.02.08 |