DjangoRestFramework 使用 python 您所在的位置:网站首页 使用第三方登录 DjangoRestFramework 使用 python

DjangoRestFramework 使用 python

2023-08-14 13:34| 来源: 网络整理| 查看: 265

本文为 social-auth-app-django 使用记录。(官方文档)

0. 前言

前提:有两个网站,记为网站A、网站B,两个网站有各自的用户系统,现在网站B要实现使网站A的用户无需注册直接登录自己的网站,这里就要用到第三方登录。

环境: Django == 3.x  social-auth-app-django == 4.0.0

1. 安装  pip install social-auth-app-django 2. 使用

网站A 为该篇文章的 provider 项目,即 OAuth provider(提供方); 

创建 Django 项目(网站B),即 OAuth consumer(使用方),网站B目录树如下图:

├─manage.py ├─social │ │ asgi.py │ │ settings.py │ │ urls.py │ │ wsgi.py │ └─ __init__.py └─users │ admin.py │ apps.py │ backends.py │ models.py │ tests.py │ views.py └─ __init__.py

并进行相关配置: 

# social/settings.py INSTALLED_APPS = [ ... 'users', 'social_django', # add ] SOCIAL_AUTH_ADMIN_USER_SEARCH_FIELDS = ['username', 'email'] # SOCIAL_AUTH_要使用登录模块的名称大写_KEY # 登录模块名对应为第三步中自定义后端的 name 属性 SOCIAL_AUTH_DJANGO_KEY = 'local' SOCIAL_AUTH_DJANGO_SECRET = 'local' # 登录成功后跳转页面 LOGIN_REDIRECT_URL = '/admin/' # 获取授权码的标识 PARTIAL_PIPELINE_TOKEN_NAME = 'code' AUTHENTICATION_BACKENDS = ( 'users.backends.djangoOauth2', # 自定义第三方登录认证 'django.contrib.auth.backends.ModelBackend', # django 默认登录认证 ) # 获取用户详细的信息 SOCIAL_AUTH_PIPELINE = ( 'social_core.pipeline.social_auth.social_details', 'social_core.pipeline.social_auth.social_uid', 'social_core.pipeline.social_auth.social_user', 'social_core.pipeline.user.get_username', 'social_core.pipeline.user.create_user', 'social_core.pipeline.social_auth.associate_user', 'social_core.pipeline.social_auth.load_extra_data', 'social_core.pipeline.user.user_details', ) TEMPLATES = [ { ... 'OPTIONS': { 'context_processors': [ ... # add 'social_django.context_processors.backends', 'social_django.context_processors.login_redirect', ], }, }, ] # social/urls.py urlpatterns = [ path('admin/', admin.site.urls), path('', include('social_django.urls', namespace='social')) # add ]  3.自定义认证后端 

配置文件 settings.py 中的 AUTHENTICATION_BACKENDS 下自定义了一个 djangoOauth2,代码实现如下:

# users/backends.py import requests from social_core.backends.oauth import BaseOAuth2 class djangoOauth2(BaseOAuth2): name = 'django' # 调用的第三方名称, 如 google AUTHORIZATION_URL = 'http://127.0.0.1:8000/o/authorize/' # 获取授权码的路由 ACCESS_TOKEN_URL = 'http://127.0.0.1:8000/o/token/' # 获取 token 的路由 ACCESS_TOKEN_METHOD = 'POST' # 获取 token 的请求方式 RESPONSE_TYPE = 'code' REDIRECT_STATE = False STATE_PARAMETER = False EXTRA_DATA = [ ('id', 'id'), ('username', 'username'), ] def get_user_details(self, response): """Return user details from Django siteA. """ print('get_user_details') return response def user_data(self, access_token, response=None, *args, **kwargs): """Return user data""" # 本处使用了用户id获取用户详细信息 # 由于网站A(provider)项目中返回的 token 信息并不包含 id 信息 # 因此这里网站A 自定义了返回 token信息(代码见下) url = 'http://127.0.0.1:8000/users/{}'.format(response['id']) headers = {'Authorization': 'Bearer ' + access_token} user_data = self.get_json( url=url, method='GET', headers=headers ) print(user_data) return user_data

注意:此处为网站A(provider)中自定义的 token 代码:

# provider/users/views.py import json from django.http import HttpResponse from django.utils.decorators import method_decorator from django.views.decorators.debug import sensitive_post_parameters from oauth2_provider.models import get_access_token_model from oauth2_provider.signals import app_authorized from oauth2_provider.views import TokenView class CustomTokenView(TokenView): """ 自定义返回令牌 """ @method_decorator(sensitive_post_parameters("password")) def post(self, request, *args, **kwargs): url, headers, body, status = self.create_token_response(request) if status == 200: body = json.loads(body) access_token = body.get("access_token") if access_token is not None: token = get_access_token_model().objects.get(token=access_token) app_authorized.send(sender=self, request=request, token=token) body['id'] = token.user.id body = json.dumps(body) response = HttpResponse(content=body, status=status) for k, v in headers.items(): response[k] = v return response # provider/urls.py import oauth2_provider.views as oauth2_views from django.conf import settings from django.contrib import admin from django.urls import path, include from users.views import UserList, UserDetails, CustomTokenView # OAuth2 provider endpoints oauth2_endpoint_views = [ path('authorize/', oauth2_views.AuthorizationView.as_view(), name="authorize"), # 这里使用自定义 token 信息 path('token/', CustomTokenView.as_view(), name="token"), path('revoke_token/', oauth2_views.RevokeTokenView.as_view(), name="revoke-token"), ] if settings.DEBUG: # OAuth2 Application Management endpoints oauth2_endpoint_views += [ path('applications/', oauth2_views.ApplicationList.as_view(), name="list"), path('applications/register/', oauth2_views.ApplicationRegistration.as_view(), name="register"), path('applications//', oauth2_views.ApplicationDetail.as_view(), name="detail"), path('applications//delete/', oauth2_views.ApplicationDelete.as_view(), name="delete"), path('applications//update/', oauth2_views.ApplicationUpdate.as_view(), name="update"), ] # OAuth2 Token Management endpoints oauth2_endpoint_views += [ path('authorized-tokens/', oauth2_views.AuthorizedTokensListView.as_view(), name="authorized-token-list"), path('authorized-tokens//delete/', oauth2_views.AuthorizedTokenDeleteView.as_view(), name="authorized-token-delete"), ] urlpatterns = [ path('admin/', admin.site.urls), # path('o/', include('oauth2_provider.urls', namespace='oauth2_provider')), # before path('o/', include((oauth2_endpoint_views, 'oauth2_provider'), namespace="oauth2_provider")), # now path('users/', UserList.as_view()), path('users//', UserDetails.as_view()), ]  4. 在网站A中注册网站B

注意:此时网站A在8000端口运行,网站B在8001端口运行。

网站B要想调用网站A登录,则需要在网站A中注册自己网站的信息,注册地址为:http://127.0.0.1:8000/o/applications/, 点击 New Applications 进行添加:

其中填写的 client_id 对应配置文件 settings.py 中的 SOCIAL_AUTH_DJANGO_KEY, client_secret 对应 SOCIAL_AUTH_DJANGO_SECRRT。

授权类型为授权码类型(authorization);

重定向地址为 http://127.0.0.1:8001/complete/django/,其中 8001 为网站B运行的端口,django 为自定义认证后端类中的 name。

5. 调用第三方登录

在浏览器中输入 http://127.0.0.1:8001/login/django/,

会发现重定向路由为 http://127.0.0.1:8000/o/authorize/?client_id=local&redirect_uri=http://127.0.0.1:8001/complete/django/&response_type=code,

输入网站A中的用户名及密码,点击授权(Authorize), 

会发现网址重定向到了 http://127.0.0.1:8001/admin/login/?next=/admin/,红字表示已经使用网站A中的 admin 用户登录成功,但是该用户没有访问该页面的权限(superuser才可以访问)。

 同时Pycharm中会输出:

 创建网站B的超级用户(social)并查看 http://127.0.0.1:8001/admin 界面:



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有