使用OAuth在web应用程序中验证Zendesk AP亚博I请求
在本教程中,您将构建一个实现OAuth授权流的web应用程序。OAuth授权的主要目标是允许第三方应用程序与Zendesk Support实例交互,而不必存储和使用Zendesk Support用户的密码,这是应用程序不应该知道的敏感信息。亚博
使用基本身份验证时,必须指定带有密码或API令牌的用户名。例子:
旋度https://{子域名}.亚博zendesk.com/api/v2/tickets.json\
- u{email_address}:{密码}
使用OAuth身份验证,应用程序指定OAuth访问令牌在HTTP头中,如下所示:
旋度https://{子域名}.亚博zendesk.com/api/v2/tickets.json\
- h"授权:持有者{access_token}"
如果用户没有访问令牌,应用程序必须将用户发送到Zendesk支持授权页面,用户可以或不可以授权应用程序代表他们访问Zendesk支持。亚博如果用户授权访问,Zendesk Support为应用程序提供亚博一个授权代码,它可以交换访问令牌。每个授权该应用程序的用户都会获得不同的访问令牌。该应用程序永远不会学习用户的Zendesk支持密码。亚博
本教程的目标是向您展示如何在web应用程序中实现OAuth授权授予流。为了简单起见,该应用程序是使用Python微web框架构建的<一个href="http://bottlepy.org/docs/dev/">瓶一个>.该框架有助于将技术细节降至最低,以便您可以专注于授权流程。
要在Zendesk应用程序中实现OAuth身份验证,请参见亚博<一个href="//www.ying8.net/documentation/apps/build-an-app/adding-third-party-oauth-to-a-support-app/">将第三方OAuth添加到支持应用程序一个>.
有关在Zendesk Support中使用OAuth的更多信息,请参见亚博<一个href="https://support.zendesk.com/hc/en-us/articles/203663836">对应用程序使用OAuth身份验证一个>.
免责声明: 亚博Zendesk提供本文仅用于教学目的。亚博Zendesk不支持或保证该代码。亚博Zendesk也不能提供对第三方技术的支持,比如Python和Bottle框架。
你需要什么
你需要一个文本编辑器和一个命令行界面,就像Windows中的命令提示符或Mac上的Terminal。
您还需要Python和一些Python库来开发web应用程序,如下所述。
安装Python 3
如果您的计算机上还没有Python版本3,请安装它。Python是一种强大但初学者友好的脚本和编程语言,具有清晰易读的语法。参观<一个href="http://www.python.org/about/">Python网站一个>了解更多。要下载并安装它,请参见<一个href="http://www.python.org/download/">http://www.python.org/download/一个>.
如果您有任何问题,请参阅<一个href="https://pip.pypa.io/en/latest/installing.html">皮普的指令一个>.
在复制本教程中的Python代码时,请确保精确地按所示缩进行。在Python中缩进很重要。
安装要求
请求一个>是一个简化HTTP请求的库。在命令行界面使用pip命令下载并安装:
pip3美元安装请求
如果您有任何问题,请参阅<一个href="https://请求.readthedocs.io/en/latest/user/install/">请求指令一个>.
安装瓶
使用以下pip命令下载并安装<一个href="http://bottlepy.org/docs/dev/index.html">瓶一个>是Python的微web框架。
pip3美元安装瓶
如果您有任何问题,请参阅<一个href="http://bottlepy.org/docs/dev/tutorial.html">瓶指令一个>.
获取教程应用程序文件
在实现OAuth授权流程之前,您需要一个工作的web应用程序。为了保持简单,教程应用程序使用了一个名为Bottle的微网络框架。一个Bottle应用程序的所有逻辑都可以轻松地放在一个文件中。因为这不是一个Bottle教程,所以提供了一组初始文件。
为了保持对OAuth流程的关注,应用程序将限制自己获取和显示用户的Zendesk Support用户名和角色,可以是管理员、代理或最终用户。亚博
本节涵盖的主题:
下载教程应用程序文件
如果你还没有教程文件夹,创建一个教程文件夹。
下载<一个href="https://zen-marketing-documentation.s3.amazonaws.com/docs/developer/oauth_tutorial_app.zip">oauth_tutorial_app.zip一个>然后将文件解压缩到教程文件夹中。
zip文件包含教程应用程序的起始文件。请参阅下一节了解有关文件以及Bottle如何工作的更多信息。
瓶子应用程序基础
导航到oauth_tutorial_app文件浏览器中的文件夹。该应用程序由以下文件夹和文件组成:
/oauth_tutorial
oauth_app.py
/静态
/的观点
的oauth_app.py文件是应用程序的神经中枢。在文本编辑器中打开它,看看:
从瓶进口路线,模板,重定向,static_file,错误,请求,响应,运行
@route(“/ home”)
defshow_home():
返回模板(“回家”)
@route(' / ')
defhandle_root_url():
重定向(“/ home”)
@route(' 亚博/ zendesk_profile ')
defmake_request():
#创建API请求
profile_data={“名字”:“Lea李”,“角色”:“管理”}
返回模板(“细节”,数据=profile_data)
@route(' / css / <文件名>”)
defsend_css(文件名):
返回static_file(文件名,根=静态/ css的)
@error(404)
def那么error404(错误):
返回模板(“错误”,error_msg=404错误。这里没什么好看的。”)
运行(宿主=“localhost”,港口=8080,调试=真正的)
该文件由路线将HTTP请求映射到函数。每个函数的返回值在HTTP响应中发送。
例如,当浏览器请求页面时<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">/家庭代码>相对URL,应用程序查找/家庭路由并运行<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">show_home ()代码>自定义函数。的<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">show_home ()代码>函数返回框架的<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">模板()代码>函数。的<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">模板()代码>函数在HTML中呈现一个名为'home'的模板。模板位于的观点文件夹和。tpl文件扩展名。
这是home.tpl模板:
<超文本标记语言>
<头>
<标题>Oauth教程应用程序的家标题>
<链接href="/ css / main.css"rel="样式表">
头>
<身体>
<h2>欢迎来到OAuth教程应用程序h2>
<一个href="亚博zendesk_profile">获取Ze亚博ndesk个人资料。一个>
身体>
超文本标记语言>
主模板包含一个指向“zendesk_profile”的链接,该链接由亚博/亚博 zendesk_profile在oauth_app.py文件:
@route(' 亚博/ zendesk_profile ')
defmake_request():
#获取用户数据
profile_data={“名字”:“Lea李”,“角色”:“管理”}
返回模板(“细节”,数据=profile_data)
的<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">模板()代码>方法中包含的信息profile_data变量添加到模板中数据关键字参数。参数名是任意的。目前,该函数将发送虚拟数据,直到稍后添加请求代码。
类中的占位符处插入参数值details.tpl模板:
<p>你好,{{数据['名字']}}。您是Zendesk亚博 Support {{data['role']}}。p>
占位符包含用于从字典中读取数据的标准Python表达式。可能的值为<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">数据(的作用)代码>是“终端用户”、“代理”和“管理员”。
最后,oauth_app.py文件调用框架的<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">run ()代码>在本地web服务器上运行应用程序的函数:
运行(宿主=“localhost”,港口=8080,调试=真正的)
Bottle框架包括一个内置的开发服务器,在将更改部署到远程服务器之前,您可以使用该服务器在本地测试更改。
要了解关于框架的更多信息,请参见<一个href="http://bottlepy.org/docs/dev/">瓶子:Python Web框架一个>在Bottle网站上。
运行应用程序
在命令行界面中,导航到oauth_tutorial_app文件夹中。
运行命令启动本地服务器。
$ python3 oauth_app.py
在浏览器中,转到<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">http://localhost:8080/home代码>.
你应该看到教程应用的主页:
做些测试
试着点击主页上的链接。试着打开<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">http://localhost:8080/代码>.
完成后,切换到命令行界面并按Ctrl+C关闭服务器。
您已经准备好开始实现OAuth授权流了。第一步是向Zendesk Support注册你的新应用。亚博
向Zendesk Support注册你的应用亚博
在使用OAuth身份验证之前,您需要告诉Zendesk Support您的应用程序。亚博您必须以Zendesk Support管理员身份登录才亚博能注册应用程序。
在<一个href="https://support.zendesk.com/hc/en-us/articles/217743418">管理中心一个>,按应用程序和集成图标(),然后选择api>亚博Zendesk API.
单击OAuth客户选项卡,然后单击亚博添加客户端在客户列表的右侧。
出现一个用于注册应用程序的页面。的秘密字段是预先填充的。
请填写以下字段:
客户端名称——输入OAuth教程应用程序.当用户被要求授予对应用程序的访问权限时,以及当他们查看有权访问Zendesk Support实例的第三方应用程序列表时,将看到这个名称。亚博
描述-可选,但您可以输入类似“此应用程序从您的Zendesk支持配置文件获取信息”之类的内容。亚博当要求用户授予访问权限时,用户将看到这个简短的描述。
公司-可选,但你可以输入你的公司名称,如果你喜欢。这是用户在被要求授予对应用程序的访问权限时将看到的公司名称。这些信息可以帮助他们了解他们授权访问的对象。
标志—可选,但可以上传logo-small.jpg在启动器文件的/static/images/文件夹中的示例图像。这是用户在被要求授予对应用程序的访问权限时将看到的标志。图像可以是JPG、GIF或PNG。为获得最佳效果,请上传正方形图像。它将根据授权页面调整大小。
唯一标识符-单击该字段,自动填充您为应用程序输入的名称。如果您愿意,可以更改它。
重定向url—输入如下URL:
http://localhost:8080/handle_user_decision代码>
Zendesk Support将使用这个U亚博RL发送用户决定授予应用程序访问权限。您将为<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">handle_user_decision代码>以后。
点击保存.
下一页将提示您保存秘密。
复制秘密珍惜并保存在安全的地方。
这些字符可能会超出文本框的宽度,因此请确保在复制之前全部选中。
重要的:出于安全考虑,您的秘密只完整显示一次。在点击保存在美国,你只能看到前9个字符。
点击保存.
现在您已经向Zendesk Support注册了应用程序,您可以修改它,在用户第亚博一次尝试使用您的应用程序访问Zendesk Support数据时,将用户发送到Zendesk Support授权页面。
将用户发送到Zendesk Support亚博授权页面
对应用程序进行的第一个更改是,如果用户还没有对应用程序进行授权,则将用户发送到Zendesk Support授权页面。亚博下面是你要实现的逻辑:如果用户有访问令牌,则发出请求。如果没有,启动授权流。
打开oauth_app.py文件并更改/亚博 zendesk_profile路线如下:
@route(' 亚博/ zendesk_profile ')
defmake_request():
has_token=假
如果has_token:
#获取用户数据
profile_data={“名字”:“Lea李”,“角色”:“管理”}
返回模板(“细节”,数据=profile_data)
确保这些行是缩进的,如图所示。
的<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">make_request ()代码>函数首先检查用户是否具有访问令牌。如果他们有一个令牌(如果has_token是true),应用程序立即发出API请求。你会代替临时的<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">has_token代码>在教程后面的代码。您还将添加API请求代码。目前使用虚拟数据。
添加一个<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">其他的代码>子句来启动授权流,如果用户没有令牌(如果has_token是假的):
其他的:
#启动授权流程
参数={}
url=“https://{子域名}.zendes亚博k.com/oauth/authorizations/new ?”+参数
重定向(url)
一定要更换<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">{子域名}代码>在URL中添加Zendesk Suppor亚博t子域。
如果用户没有令牌,他们会被重定向到Zendesk Support授权页面。亚博
您必须将查询字符串中的某些参数与URL一起发送,如下所述。亚博Zendesk Support使用这些参数为用户定制授权页面。
属性中添加以下名称/值对参数中的变量<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">其他的代码>条款:
参数={
“response_type”:“代码”,
“redirect_uri”:“http://localhost: 8080 / handle_user_decision”,
“client_id”:“oauth_tutorial_app”,
“范围”:阅读写的
}
因为应用程序使用授权代码授予流程,你必须详细说明<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">“代码”代码>作为响应类型。的<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">“redirect_uri”代码>值是你想让Zendesk Support发送用户亚博决定的位置。的<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">“client_id”代码>value是在Zendesk Support中注册应用程序时创建的“唯一标识符”。亚博的<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">“范围”代码>value是应用程序在Zendesk Support中请求允许做的事情。亚博如果应用程序只获取数据而不创建数据,你可以指定'read'作为作用域。
参数必须经过url编码,以便在查询字符串中发送,如下所述。
通过参数变量为<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">urlencode ()代码>方法中的url变量声明:
url=“……/ oauth /授权/新的?”+urlencode(参数)
的顶部添加下面的行oauth_app.py导入urlencode方法:
从urllib.解析进口urlencode
的<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">urllib.parse代码>模块包含在Python中,所以你不必安装它。
的值更新后的路由应该如下所示<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">{子域名}代码>占位符:
@route(' 亚博/ zendesk_profile ')
defmake_request():
has_token=假
如果has_token:
#获取用户数据
profile_data={“名字”:“Lea李”,“角色”:“管理”}
返回模板(“细节”,数据=profile_data)
其他的:
#启动授权流程
参数={
“response_type”:“代码”,
“redirect_uri”:“http://localhost: 8080 / handle_user_decision”,
“client_id”:“oauth_tutorial_app”,
“范围”:阅读写的}
url=“https://{子域名}.zendes亚博k.com/oauth/authorizations/new ?”+urlencode(参数)
重定向(url)
确保你的代码是缩进的,忽略任何由右边距引起的换行,然后测试它是否工作:
从命令行启动开发服务器:
$ python3 oauth_app.py
如果服务器仍在运行上一个会话,请使用Ctrl+C关闭它,并重新启动它,以便更改生效。
开放<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">http://localhost:8080/home代码>在浏览器中。
点击获取Ze亚博ndesk个人资料.
您应该被重定向到Zendesk支持授权页面,因为亚博<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">has_token代码>是假的。如果您目前尚未登录Zendesk技术支持,系统将要求您先登录。亚博这就是Zendesk S亚博upport如何知道您是谁。
最终,授权页面打开:
不要点击允许然而。重定向页面还不存在。你接下来要做的就是这个。如果你点击允许这不是世界末日。正如预期的那样,您只会得到404消息。
请注意:如果对oauth_app.py在本地服务器运行时,您必须停止并重新启动服务器才能查看更改。如果对模板或css等静态文件进行更改,则不必重新启动服务器。只需在浏览器中刷新页面。
处理用户的授权决策
当用户在Zendesk Support授权页面上做出允许或拒绝访问应用程序的决定后亚博,Zendesk Support将决定和其他一些信息发送到您指定的重定向URL。
如果用户决定授权应用程序,Zendesk Support会添加一个包含授权代码的查询字符串。亚博例子:
{redirect_url}?代码=7xqwtlf3rrdj8uyeb1yf
如果用户决定不授权应用程序,Zendesk Support将添加一个查询字符串,其中包含亚博错误而且error_description通知应用程序用户拒绝访问的参数。例子:
{redirect_url}?错误=access_denied&error_description=的+结束-用户+或+授权+服务器+否认+的+请求
使用可能的查询字符串值来控制应用程序的流程。下面是你可以采取的方法:如果查询字符串包含字符串'error',则显示错误消息。如果没有,请获取访问令牌。
首先为“/handle_user_decision”重定向URL创建一个路由:
@route(' / handle_user_decision ')
defhandle_decision():
如果“错误”在请求.query_string:
返回模板(“错误”,error_msg=请求.查询.error_description)
其他的:
#获取访问令牌
的<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">handle_decision ()代码>函数检查字符串'error'是否出现在查询字符串中。在Bottle框架中,<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">请求代码>对象引用当前HTTP请求<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">query_string代码>属性引用请求的查询字符串(如果有的话)。
如果发现'error',应用程序会渲染错误模板,并显示来自error_description参数。
如果没有发现'error',则必须发送了授权代码。应用程序可以从查询字符串中获取代码,并将其与特定API端点的POST请求交换为访问令牌,如下所述。
在<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">其他的代码>子句,定义POST请求中必须包含的参数:
参数={
“grant_type”:“authorization_code”,
“代码”:请求.查询.代码,
“client_id”:“oauth_tutorial_app”,
“client_secret”:“{your_secret}”,
“redirect_uri”:“http://localhost: 8080 / handle_user_decision”,
“范围”:“读”}
的<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">“grant_type”代码>值为'authorization_code',因为您正在实现授权代码授予流。的<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">“代码”代码>值为实际授权代码,该代码从查询字符串中检索<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">query.code代码>框架的属性<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">请求代码>对象。的<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">“秘密”代码>值是在Zendesk Support中注册应用程序时生成的“Secret”。亚博的<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">“redirect_uri”代码>value是与之前相同的重定向URL。
在参数后添加以下语句来进行POST请求:
有效载荷=json.转储(参数)
头={“内容类型”:“application / json”}
url=“https://{子域名}.zendes亚博k.com/oauth/tokens”
r=请求.帖子(url,数据=有效载荷,头=头)
一定要更换<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">{子域名}代码>在URL中添加Zendesk Suppor亚博t子域。
的<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">requests.post ()代码>方法发出请求。Zendesk Support的响应亚博被分配给<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">r代码>变量。(<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">响应代码>标识符为Bottle保留<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">响应代码>下一步中使用的对象。)
处理响应:
如果r.status_code! =200:
error_msg=“获取访问令牌失败,错误为{}”.格式(r.status_code)
返回模板(“错误”,error_msg=error_msg)
其他的:
数据=r.json()
响应.set_cookie(“owat”,数据[“access_token”])
重定向(' 亚博/ zendesk_profile ')
如果请求成功(HTTP状态代码为200),则<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">其他的代码>子句被执行。应用程序解码json数据并获得令牌。然后,它将令牌保存在名为“owat”(用于oauth web应用程序教程)的cookie中,并与框架一起保存在用户的计算机上<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">response.set_cookie ()代码>方法。
重要的:为了简单起见,该应用程序将令牌保存在用户机器上的cookie中,但要注意安全隐患。这就像在cookie中保存密码一样。有人可以使用它来访问用户在Zendesk Support上的信息。亚博不幸的是,安全地存储访问令牌超出了本教程的范围。
最后,用户被重定向到亚博zendesk_profile页面,该页面启动了授权流程。
在文件顶部添加以下代码中使用的库:
进口json
进口请求
完成的/ handle_user_decisionRoute应该如下所示(确保缩进是正确的,忽略由右边距引起的换行):
@route(' / handle_user_decision ')
defhandle_decision():
如果“错误”在请求.query_string:
返回模板(“错误”,error_msg=请求.查询.error_description)
其他的:
#获取访问令牌
参数={
“grant_type”:“authorization_code”,
“代码”:请求.查询.代码,
“client_id”:“oauth_tutorial_app”,
“client_secret”:“{your_secret}”,
“redirect_uri”:“http://localhost: 8080 / handle_user_decision”,
“范围”:“读”}
有效载荷=json.转储(参数)
头={“内容类型”:“application / json”}
url=“https://{子域名}.zendes亚博k.com/oauth/tokens”
r=请求.帖子(url,数据=有效载荷,头=头)
如果r.status_code! =200:
error_msg=“获取访问令牌失败,错误为{}”.格式(r.status_code)
返回模板(“错误”,error_msg=error_msg)
其他的:
数据=r.json()
令牌=数据[“access_token”]
响应.set_cookie(“owat”,令牌)
重定向(' 亚博/ zendesk_profile ')
使用访问令牌
您的应用程序现在可以检查用户是否有访问令牌。如果令牌存在,应用程序可以使用它向Zendesk Support请求用户的信息。亚博
在/亚博 zendesk_profile路由,替换如下2行:
has_token=假
如果has_token:
在相同的缩进级别上使用以下行:
如果请求.get_cookie(“owat”):
该应用程序使用Bottle框架检查名为“owat”的cookie是否存在于用户的计算机上<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">request.get_cookie ()代码>方法。如果cookie存在,它将从Zendesk Support获取用户数据。亚博如果cookie不存在,应用程序启动授权流程。
的内容<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">如果代码>子句中包含以下请求代码:
#获取用户数据
access_token=请求.get_cookie(“owat”)
bearer_token=“持票人”+access_token
头={“授权”:bearer_token}
url=“https://{子域名}.zendes亚博k.com/api/v2/users/me.json”
r=请求.得到(url,头=头)
如果r.status_code! =200:
error_msg=“获取数据失败,错误为{}”.格式(r.status_code)
返回模板(“错误”,error_msg=error_msg)
其他的:
数据=r.json()
profile_data={
“名字”:数据[“用户”][“名字”],
“角色”:数据[“用户”][“角色”]}
返回模板(“细节”,数据=profile_data)
一定要更换<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">{子域名}代码>在URL中添加Zendesk Suppor亚博t子域。
前三行构建授权标头:
access_token=请求.get_cookie(“owat”)
bearer_token=“持票人”+access_token
头={“授权”:bearer_token}
块的其余部分使用授权标头发出请求,更新profile_data变量,并显示带有用户概要信息的详细信息页面。要了解有关发出API请求的更多信息,请参见<一个href="//www.ying8.net/documentation/ticketing/getting-started/making-requests-to-the-zendesk-api/">向Ticketing API发出请求一个>.
代码完成
应用程序已经完成并准备测试。这是完成的版本oauth_app.py文件:
从urllib.解析进口urlencode
进口json
进口请求
从瓶进口路线,模板,重定向,static_file,错误,请求,响应,运行
@route(“/ home”)
defshow_home():
返回模板(“回家”)
@route(' 亚博/ zendesk_profile ')
defmake_request():
如果请求.get_cookie(“owat”):
#获取用户数据
access_token=请求.get_cookie(“owat”)
bearer_token=“持票人”+access_token
头={“授权”:bearer_token}
url=“https://your_subdomain.亚博zendesk.com/api/v2/users/me.json”
r=请求.得到(url,头=头)
如果r.status_code! =200:
error_msg=“获取数据失败,错误为{}”.格式(r.status_code)
返回模板(“错误”,error_msg=error_msg)
其他的:
数据=r.json()
profile_data={
“名字”:数据[“用户”][“名字”],
“角色”:数据[“用户”][“角色”]}
返回模板(“细节”,数据=profile_data)
其他的:
#启动授权流程
参数={
“response_type”:“代码”,
“redirect_uri”:“http://localhost: 8080 / handle_user_decision”,
“client_id”:“oauth_tutorial_app”,
“范围”:阅读写的}
url=“https://your_subdomain.亚博zendesk.com/oauth/authorizations/new?”+urlencode(参数)
重定向(url)
@route(' / handle_user_decision ')
defhandle_decision():
如果“错误”在请求.query_string:
返回模板(“错误”,error_msg=请求.查询.error_description)
其他的:
#获取访问令牌
参数={
“grant_type”:“authorization_code”,
“代码”:请求.查询.代码,
“client_id”:“oauth_tutorial_app”,
“client_secret”:“your_secret”,
“redirect_uri”:“http://localhost: 8080 / handle_user_decision”,
“范围”:“读”}
有效载荷=json.转储(参数)
头={“内容类型”:“application / json”}
url=“https://your_subdomain.亚博zendesk.com/oauth/tokens”
r=请求.帖子(url,数据=有效载荷,头=头)
如果r.status_code! =200:
error_msg=“获取访问令牌失败,错误为{}”.格式(r.status_code)
返回模板(“错误”,error_msg=error_msg)
其他的:
数据=r.json()
响应.set_cookie(“owat”,数据[“access_token”])
重定向(' 亚博/ zendesk_profile ')
@route(' / ')
defhandle_root_url():
重定向(“/ home”)
@route(' / css / <文件名>”)
defsend_css(文件名):
返回static_file(文件名,根=静态/ css的)
@error(404)
def那么error404(错误):
返回模板(“错误”,error_msg=404错误。这里没什么好看的。”)
运行(宿主=“localhost”,港口=8080,调试=真正的)
确保缩进是正确的,然后运行应用程序来测试它。
启动本地服务器:
$ python3 oauth_app.py
在浏览器中,转到<代码数据-garden-id="typography.code" data-garden-version="8.39.0" class="sc-eKYRIR sc-bTDOke bpSbjj iFHZBF">http://localhost:8080/home代码>.
做些测试
如果可以,尝试以不同的Zendesk Support用户使用不同的浏览器。亚博
完成后,切换到命令行界面并按Ctrl+C关闭服务器。
如果你愿意,你可以继续调整或添加应用程序。有关更多信息,请参阅以下资源:亚博电脑端