005-Django OAuth Toolkit 身份认证
Django OAuth Toolkit 身份认证1、最小化安装配置2、创建 API3、注册一个应用程序4、获取 token 并访问 APIDjango OAuth Toolkit + Django REST Framework 身份认证。API 官方地址:https://django-oauth-toolkit.readthedocs.io/en/latest/rest-framework/..
Django OAuth Toolkit 身份认证
Django OAuth Toolkit + Django REST Framework 身份认证。
API 官方地址:https://django-oauth-toolkit.readthedocs.io/en/latest/rest-framework/getting_started.html
1、最小化安装配置
1)创建一个虚拟环境,并在虚拟环境中安装以下包:
pip install django-oauth-toolkit djangorestframework
2)将 rest_framework 和 oauth2_provider 添加到 INSTALLED_APPS 设置中:
INSTALLED_APPS = (
'django.contrib.admin',
...
'oauth2_provider',
'rest_framework',
)
3)现在需要告诉 Django REST Framework 使用新的身份验证后端。为此,需要在 settings.py 的末尾添加以下行:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'oauth2_provider.contrib.rest_framework.OAuth2Authentication',
)
}
2、创建 API
2.1 基于函数的 API 视图
https://django-oauth-toolkit.readthedocs.io/en/latest/views/function_based.html
Django OAuth Toolkit 提供了装饰器来帮助保护基于功能的视图:
protected_resource(scopes=None, validator_cls=OAuth2Validator, server_cls=Server)
rw_protected_resource(scopes=None, validator_cls=OAuth2Validator, server_cls=Server)
from oauth2_provider.decorators import protected_resource
@protected_resource()
def my_view(request):
# ...
pass
return HttpResponse(json.dumps({'status':'success'}, ensure_ascii=False))
from oauth2_provider.decorators import rw_protected_resource
@rw_protected_resource()
def my_view(request):
# If this is a POST, you have to provide 'write' scope to get here...
# ...
pass
return HttpResponse(json.dumps({'status':'success'}, ensure_ascii=False))
# 根路由下添加
path('one/', include('fristapp.urls')),
# fristapp 下添加
path('myo/', my_view),
2.2 基于类的 API 视图
https://django-oauth-toolkit.readthedocs.io/en/latest/views/class_based.html
Django OAuth Toolkit 提供了一些泛型类,它们对于使用基于类的视图方法实现 OAuth2 受保护的端点非常有用,继承类:
ProtectedResourceView --- ProtectedResourceView(ProtectedResourceMixin, View)
ScopedProtectedResourceView --- ScopedProtectedResourceView(ScopedResourceMixin, ProtectedResourceView)
ReadWriteScopedResourceView --- ReadWriteScopedResourceView(ReadWriteScopedResourceMixin, ProtectedResourceView)
class MyEndpoint(ProtectedResourceView):
"""
A GET endpoint that needs OAuth2 authentication
"""
def get(self, request, *args, **kwargs):
return HttpResponse('Hello, World!')
# 根路由下添加
path('two/', include('fristapp.urls')),
# fristapp 下添加
path('myt/', MyEndpoint.as_view()),
2.3 另:权限 API 示例
1)创建序列化类 serializers.py
from django.contrib.auth.models import User
from rest_framework import serializers
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('username', 'email', "first_name", "last_name")
2)定义一个 API
在 app views.py 中创建一个 API:
class MyUserList(generics.ListCreateAPIView):
permission_classes = [permissions.IsAuthenticated, TokenHasReadWriteScope]
queryset = User.objects.all()
serializer_class = UserSerializer
class MyUserDetails(generics.RetrieveAPIView):
permission_classes = [permissions.IsAuthenticated, TokenHasReadWriteScope]
queryset = User.objects.all()
serializer_class = UserSerializer
3)在工程根目录下的 urls.py 中添加:
urlpatterns = [
path('myapplications/', include('oauth2_provider.urls', namespace='oauth2_provider')),
path('users/', MyUserList.as_view()),
path('users/<pk>/', MyUserDetails.as_view(), name='user-detail'),
]
注意:
MyUserDetails 类必须有,对应路由配置 name 的值必须是user-detail
。否则访问路由 users/ 将不能成功。
2.4 使用身份认证 API 准备工作
1)迁移
python manage.py migrate
2)创建用户
python manage.py createsuperuser
(tom)
3)启动项目
python manage.py runserver
4)注册一个应用程序
访问下面的链接,创建一个应用程序实例:
http://127.0.0.1:8000/myapplications/applications/
- Name: 仅仅只是一个名称
- Client Type: confidential
- Authorization Grant Type: Resource owner password-based
3、获取 token 并访问 API
获取 token:
import requests
def getToke():
'''
获取token
:return:
'''
url = 'http://127.0.0.1:8000/myapplications/token/'
params = {
'grant_type': 'password',
'username': 'tom', # user,用户名
'password': 'xxxxxx' # 用户密码
}
client_id = 'V1fWEMB2usfdafsdfadakRT5S2eQ94q6'
client_secret = 'adfsdfVYJHnxX7F5NsDr7l9CEKACqdfaercatewewrw'
auth = HTTPBasicAuth(client_id, client_secret)
data = requests.post(url=url, data=params, auth=auth)
text = data.json()
''' text 为字典,内容如下:
{
"access_token": "wnS6nkwusdw3sUdzQvH54dfdfw",
"expires_in": 36000,
"token_type": "Bearer",
"scope": "read write groups",
"refresh_token": "sadfIPmkZywCC45oIIgrJTRDWBKad"
}
'''
return text
访问 API:
def testApi():
'''
访问API
:return:
'''
dt = getToke()
url = 'http://127.0.0.1:8000/one/myo/'
url = 'http://127.0.0.1:8000/two/myt/'
url = 'http://127.0.0.1:8000/users/'
headers = {
"Authorization": f"{dt['token_type']} {dt['access_token']}"
}
# 有权限访问
data = requests.get(url=url, headers=headers)
text = data.json() # [{'username': 'tom', 'email': 'tom@163.com', 'first_name': '', 'last_name': ''}]
# 没有权限访问
data = requests.get(url=url)
text = data.json() # {'detail': 'Authentication credentials were not provided.'}
if __name__ == '__main__':
testApi()
更多推荐
所有评论(0)