第一个带认证的连接器
我们在对接三方系统的时候,一般情况下三方系统都需要进行身份认证,并且认证信息在后续的接口调用中需要使用。因此连接器实现时,需要有一个专门的模块来维护身份认证过程。
接下来我们以连接天智的FastBI系统为例来介绍一下如何实现身份认证。
1:确定认证方案
在开始编码之前,首先需要先研究你要对接的第三方服务的认证机制:
- 查阅第三方服务的API文档,了解其认证方式
- 确定需要用户提供哪些 信息(用户名、密码、API Key等)
- 确定认证流程(Basic认证、OAuth2、自定义Token等)
常见的认证类型:
- Basic/Digest认证 :最简单的HTTP认证方式,直接使用用户名和密码
- Custom认证 :自定义认证流程,常用于Token机制
- OAuth2认证 :标准的OAuth2流程,适用于多数现代Web服务
天智FastBI系统采用的是Token机制,因此我们使用Custom认证模式
2:创建认证配置
你需要在连接器中创建一个认证配置字典,这个字典告诉系统如何处理认证:
auth = {
'test': auth_test,
'fields': [
# 认证字段列表
],
'auth_type': 'custom',
'config_custom': {
'implement': token_auth,
},
}
配置项详解:
- test :指向测试认证是否成功的函数
- fields :用户需要填写的认证信息字段列表
- auth_type :认证类型('basic', 'digest', 'custom', 'oauth2')
- config_custom :仅当auth_type为'custom'时需要,包含认证实现函数
3:定义认证字段
在FastBI系统中,获取token需要url username password三个字段,认证字段定义如下:
'fields': [
{
'key': 'url',
'required': True,
'label': 'URL地址',
'help_text': '登录地址',
},
{
'key': 'username',
'required': True,
'label': '用户名',
'help_text': '登录用户名',
},
{
'key': 'password',
'required': True,
'label': '密码',
'help_text': '登录密码',
},
]
字段属性说明:
- key (必需):字段的唯一标识符,后续代码中通过这个key获取字段值
- required (必需):布尔值,表示该字段是否必须填写
- label (必需):显示给用户的字段名称
- help_text (可选):对字段的进一步说明
更多的属性参考字段定义章节
4:实现认证函数
示例中的认证函数token_auth负责执行实际的认证过程,在这个过程中调用了FastBI系统的登录接口,获取到了token。该函数返回一个字典,这些数据将被缓存在系统中,后续其它动作可通过入参auth_data取得这些信息:
def token_auth(auth_data:dict, *args, **kwargs):
username: str = auth_data['username']
password: str = auth_data['password']
url: str = auth_data['url']
if not url.lower().startswith('http'):
url = 'http://' + url
url = urlparse.urljoin(url, f'/api/rest/user/login/')
response: Response = requests.request(method='POST', url=url, data={"username": username, "password": password})
token = response.json()['token']
return {"token": 'token ' + str(token)}
实现要点:
- 函数接收的第一个参数
auth_data是包含用户输入的所有认证字段的字典 - 通过字段的key从
auth_data中获取对 应值 - 执行认证逻辑(向认证服务器发送POST请求获取token)
- 返回包含认证信息的字典,供后续API调用使用
5:实现测试函数
测试函数会在前端点击授权测试的时候被触发,本例中的测试函数auth_test用于验证认证是否成功,先从入参auth_data里获取token并调用个人信息接口,如果接口调用成功则表示测试通过,需要返回True:
def auth_test(*args, ** kwargs):
auth_data = kwargs['auth_data']
token: str = auth_data['token']
url: str = auth_data['url']
headers = {'Authorization': token}
if not url.lower().startswith('http'):
url = 'http://' + url
# 发送请求
url = urlparse.urljoin(url, f'/api/rest/user/me/')
response: Response = requests.request(method='GET', url=url, headers=headers)
res: dict = response.json()
if response.status_code == 200:
return True
else:
raise Exception('授权失败!(API Token输入错误)')
实现要点:
- 从
kwargs['auth_data']中获取认证函数返回的认证信息 - 使用这些信息发送一个测试请求(获取用户信息)
- 根据响应判断认证是否有效
- 有效返回True,无效抛出异常
6:整合认证配置到API定义
将认证配置添加到你的API定义中:
def api():
auth = {
'test': auth_test,
'fields': [
{
'key': 'url',
'required': True,
'label': 'URL地址',
'help_text': '登录地址',
},
{
'key': 'username',
'required': True,
'label': '用户名',
'help_text': '登录用户名',
},
{
'key': 'password',
'required': True,
'label': '密码',
'help_text': '登录密码',
},
],
'auth_type': 'custom',
'config_custom': {
'implement': token_auth,
},
}
api_dict = {
'key': 'FastBITest',
'actions': {
# 动作定义
},
'label': 'FastBITest',
'description': '商业智能可视化数据分析工具',
"image": "https://fbi.tizdata.com/flow/FastBI.svg",
'help_url': 'https://www.yuque.com/lixuegao/yae7w2/kk1hprf8zg7bv4s7',
'authentication': auth,
'category': '数据分析',
}
return api_dict