快速入门
使用Django、Django OAuth工具包和OAuthLib构建一个OAuth2提供程序。
我们将建造什么?
我们的计划是从头开始建立一个OAuth2提供商。
在此入门指南中,我们将:
创建Django项目。
安装和配置Django OAuth工具包。
创建两个OAuth2应用程序。
使用授权码授予流。
使用客户端凭据授予流。
什么是OAuth?
OAuth是一种开放的访问授权标准,通常用于互联网用户授予网站或应用程序访问其他网站上的信息的权限,但不向他们提供密码。-- Whitson Gordon
姜戈
Django是一个高级的Python Web框架,它鼓励快速开发和干净、实用的设计。它由经验丰富的开发人员构建,解决了Web开发的大部分麻烦,因此您可以专注于编写应用程序,而不需要重新发明轮子。-- Django website
让我们从创建虚拟环境开始::
mkproject iam
这将创建、激活目录并将其切换到新的Python虚拟环境。
安装Django::
pip install Django
创建Django项目::
django-admin startproject iam
这将在当前目录中创建一个MySite目录。结构如下:
.
└── iam
├── iam
│ ├── asgi.py
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── manage.py
创建Django应用程序::
cd iam/
python manage.py startapp users
这将创建一个目录 users ,其布局如下::
.
├── iam
│ ├── asgi.py
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── manage.py
└── users
├── admin.py
├── apps.py
├── __init__.py
├── migrations
│ └── __init__.py
├── models.py
├── tests.py
└── views.py
如果您要开始一个新项目,强烈建议您设置一个自定义用户模型,即使默认情况下 User 型号对你来说就足够了。此模型的行为与默认用户模型相同,但如果将来需要,您可以对其进行定制。-- Django documentation
编辑 users/models.py 添加以下代码:
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
pass
变化 iam/settings.py 要添加 users 适用于 INSTALLED_APPS :
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'users',
]
配置 users.User 作为用于 auth 应用程序通过添加 AUTH_USER_MODEL 至 iam/settings.py :
AUTH_USER_MODEL = 'users.User'
为创建初始迁移 users 应用程序 User 型号::
python manage.py makemigrations
上面的命令将创建迁移::
Migrations for 'users':
users/migrations/0001_initial.py
- Create model User
最后执行迁移::
python manage.py migrate
这个 migrate 输出::
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions, users
Running migrations:
Applying contenttypes.0001_initial... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0001_initial... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying users.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying sessions.0001_initial... OK
Django OAuth工具包
Django OAuth工具包可以通过开箱即用地提供向Django项目添加OAuth2功能所需的所有端点、数据和逻辑来帮助您。
安装Django OAuth工具包::
pip install django-oauth-toolkit
增列 oauth2_provider 至 INSTALLED_APPS 在……里面 iam/settings.py :
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'users',
'oauth2_provider',
]
执行迁移::
python manage.py migrate
这个 migrate 命令输出::
Operations to perform:
Apply all migrations: admin, auth, contenttypes, oauth2_provider, sessions, users
Running migrations:
Applying oauth2_provider.0001_initial... OK
Applying oauth2_provider.0002_auto_20190406_1805... OK
包括 oauth2_provider.urls 至 iam/urls.py 详情如下:
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('admin/', admin.site.urls),
path('o/', include('oauth2_provider.urls', namespace='oauth2_provider')),
]
这将使端点可用于授权、生成令牌和创建OAuth应用程序。
上次更改,添加 LOGIN_URL 至 iam/settings.py :
LOGIN_URL = '/admin/login/'
我们将使用Django管理员登录,让我们的生活变得轻松。
创建用户::
python manage.py createsuperuser
Username: wiliam
Email address: me@wiliam.dev
Password:
Password (again):
Superuser created successfully.
客户端凭据
客户端凭据授予适用于机器对机器的身份验证。您可以授权您自己的服务或员工将银行帐户事务处理状态更改为已接受。
将浏览器指向http://127.0.0.1:8000/o/applications/register/,让它创建一个应用程序。
如下面截图所示填写表格,并在保存前记下 Client id 和 Client secret 我们马上就会用到。
出口 Client id 和 Client secret 作为环境变量的值:
export ID=axXSSBVuvOyGVzh4PurvKaq5MHXMm7FtrHgDMi4u
export SECRET=1fuv5WVfR7A5BlF0o155H7s5bLgXlwWLhi3Y7pdJ9aJuCdl0XV5Cxgd0tri7nSzC80qyrovh8qFXFHgFAAc0ldPNn5ZYLanxSm1SI1rxlRrWUP591wpHDGa3pSpB6dCZ
客户端凭据流比授权码流更简单。
我们需要编码 client_id 和 client_secret 中编码的基于HTTP的身份验证 base64 我使用以下代码来实现这一点。
>>> import base64
>>> client_id = "axXSSBVuvOyGVzh4PurvKaq5MHXMm7FtrHgDMi4u"
>>> secret = "1fuv5WVfR7A5BlF0o155H7s5bLgXlwWLhi3Y7pdJ9aJuCdl0XV5Cxgd0tri7nSzC80qyrovh8qFXFHgFAAc0ldPNn5ZYLanxSm1SI1rxlRrWUP591wpHDGa3pSpB6dCZ"
>>> credential = "{0}:{1}".format(client_id, secret)
>>> base64.b64encode(credential.encode("utf-8"))
b'YXhYU1NCVnV2T3lHVnpoNFB1cnZLYXE1TUhYTW03RnRySGdETWk0dToxZnV2NVdWZlI3QTVCbEYwbzE1NUg3czViTGdYbHdXTGhpM1k3cGRKOWFKdUNkbDBYVjVDeGdkMHRyaTduU3pDODBxeXJvdmg4cUZYRkhnRkFBYzBsZFBObjVaWUxhbnhTbTFTSTFyeGxScldVUDU5MXdwSERHYTNwU3BCNmRDWg=='
>>>
将凭据导出为环境变量
export CREDENTIAL=YXhYU1NCVnV2T3lHVnpoNFB1cnZLYXE1TUhYTW03RnRySGdETWk0dToxZnV2NVdWZlI3QTVCbEYwbzE1NUg3czViTGdYbHdXTGhpM1k3cGRKOWFKdUNkbDBYVjVDeGdkMHRyaTduU3pDODBxeXJvdmg4cUZYRkhnRkFBYzBsZFBObjVaWUxhbnhTbTFTSTFyeGxScldVUDU5MXdwSERHYTNwU3BCNmRDWg==
要启动您调用的客户端凭据流 /token/ 终端直接::
curl -X POST -H "Authorization: Basic ${CREDENTIAL}" -H "Cache-Control: no-cache" -H "Content-Type: application/x-www-form-urlencoded" "http://127.0.0.1:8000/o/token/" -d "grant_type=client_credentials"
要更容易地进行可视化::
curl -X POST \
-H "Authorization: Basic ${CREDENTIAL}" \
-H "Cache-Control: no-cache" \
-H "Content-Type: application/x-www-form-urlencoded" \
"http://127.0.0.1:8000/o/token/" \
-d "grant_type=client_credentials"
OAuth2提供程序将返回以下响应:
{
"access_token": "PaZDOD5UwzbGOFsQr34LQ7JUYOj3yK",
"expires_in": 36000,
"token_type": "Bearer",
"scope": "read write"
}
下一步是 first tutorial 。