我试图找出在单页面应用程序中处理权限的正确方法,该应用程序直接与几个实现HATEOAS的RESTful API对话。
举个例子:
"作为我的应用程序的用户,我可以查看,启动和暂停作业,但不能阻止它们。"
基础rest API具有以下资源:
/作业/ {ID} 哪个接受GET和PUT。 GET返回作业模型,PUT接受作业模型作为请求体:
{
"_links" : {
"self" : "/jobs/12345678"
}
"id" : 12345678,
"description" : "foo job",
"state" : "STOPPED"
}
接受的工作状态可以是:休眠|跑步|暂停了|停止。
要求说在UI上我必须有按钮:
开始,暂停,停止
...并且仅根据登录用户的权限进行显示。
从API的角度来看,一切都有效,因为服务器上的底层逻辑确保用户在发出请求时无法将状态更新为STOPPED状态(可能会返回401)。
通知app / UI用户权限的最佳方式是什么,这样可以隐藏用户无权操作的任何按钮?
API应该提供权限列表,可能是这样的:
{
"_links" : {
"self" : "/permissions",
"jobs" : "/jobs"
}
"permissions" : {
"job" : ["UPDATE", "DELETE"],
"job-updates" : ["START", "PAUSE"]
}
}
或者应该更改API以便权限反映在HATEOS链接中,例如:
{
"_links" : {
"self" : "/jobs/12345678",
"start" : "/jobs/12345678/state?to=RUNNING",
"pause" : "/jobs/12345678/state?to=PAUSED",
}
"id" : 12345678,
"description" : "foo job",
"state" : "DORMANT"
}
还是应该以完全不同的方式完成?
更新
答案 0 :(得分:5)
我会选择后者:根据存在的链接暗示权限。
如果链接不存在,则用户无法访问资源/执行操作。如果是,他们可以。这就是我要做的事情,因为它简单而干净,并且几乎没有前端代码的自由裁量权。脱钩,哟。
或者,如果做想要在每个响应中包含所有链接但是明确指定哪些是允许的,哪些不是,如果使用HAL之类的格式来编写您的链接,您可以在每个链接上使用标记扩展它,如下所示:
{
"_links" : {
"self" : {
"href":"/jobs/12345678",
"allowed":false
},
"start" : {
"href":"/jobs/12345678/state?to=RUNNING",
"allowed":false
},
"pause" : {
"href":"/jobs/12345678/state?to=PAUSED",
"allowed":false
}
},
"id" : 12345678,
"description" : "foo job",
"state" : "DORMANT"
}
答案 1 :(得分:1)
我会选择后者。我不喜欢前者的原因是因为您要为客户创建额外的工作,要求它找出权限与他们允许访问的资源之间的映射。如果您使用hateoas并检查是否存在关系类型,则服务器会为您完成此映射。这也意味着uris可以在不打破客户的情况下改变。
我最近写了一篇关于这个领域的博客文章:
https://www.opencredo.com/2015/08/12/designing-rest-api-fine-grained-resources-hateoas-hal/
答案 2 :(得分:0)
您应该使用表单而不是链接来提供状态转换超媒体。 如果您无法在媒体类型中提供表单,请提供指向使用支持表单的其他媒体类型的URI的链接,例如XHTML。
为此目的,IANA create-form
,edit-form
和delete-form
有link relations。
另外,请不要将start
和pause
用作真正的链接关系。如果您自己定义它们,它们必须是URI(最好是HTTP URL,但是您控制下的任何URI都可以)。 start
与您使用它的含义完全不同,pause
未定义。