为了账号安全,请及时绑定邮箱和手机立即绑定

《 Restful Web Services 》读书笔记 | Chapter SIX

标签:
Ruby


《 Restful Web Services 》读书笔记

第六章  Designing Read/Write Resource-Oriented Services

本章作者设计了一个可读写的面向资源服务。

作者扩展上一章的地图服务, 想设计一个用户自定义地点的地图服务来进一步说明ROA的设计。 作者把用户帐户作为资源,有两点考虑。第一, 如果和一般的web应用一样,注册一个用户,必须重载post来模拟非安全的操作。 第二, 这样会带来一些新特性,用户可以不必登陆网站来注册用户。 

认证,授权,保密和信任

       因为暴露了用户资源,当有人发来http请求,这样必然需要判断这个请求是谁发出来的,这个时候就需要认证。作者这里简单描述了这些概念:

       当web客户端发出一个请求时,它将在Authorization报头里附上一些证书(credentials)。在服务收到该请求后,它会通过检查这些证书来确定客户端是否代表某一特定帐户(认证),以及该用户是否被允许做它所请求的操作(授权)。标准的认证方案常用的有:HTTP基本认证,HTTP摘要认证(HTTP Digest)和WSSE认证。我们还需要考虑保密性,用户A的私有数据不应该被其他用户访问,如何防止不被截获呢?可以用SSL对HTTP进行加密。关于用户信任问题,HTTP标准并没有给出解决方法。

创建可读写资源的步骤:

        1. 规划数据集

         2. 把数据集划分为资源

         对于其中的每种资源:

         3. 用URI为该资源命名

         4. 暴露一个统一接口的子集

         5. 设计来自客户端的表示

         6. 设计发给客户端的表示

         7. 用超链接和表单把该资源与已有资源联系起来

         8. 考虑有哪些典型的事件经过

         9. 考虑可能出现哪些错误情况

    

比上一章讲的步骤多了第四步和第五步。

将用户帐户作为资源的设计过程:

一   规划数据集:

      显然只有用户名和密码(为了简单说明,不包含用户的其他信息,比如email和地址等)

二   把数据集划分为资源:

      按第五章的分类, 用户帐户属于第二类资源。服务通过这些资源来暴露背后的相关对象。 

三   用URI为资源命名

https:// maps.example.com/user/{user-name}

四   暴露一个统一接口的子集

      通过回答以下问题来决定暴露统一接口的哪些子集:

客户端将创建这种新资源吗?

   在本章的例子里的答案就是,当然了, 用户需要注册进入系统。

当客户端创建这种新资源时,谁负责决定这个新资源的URI?客户端还是服务端 ?

这个URI是由客户端负责的, 因为上面的步骤中uri表示里user-name是客户来写的。

通过上面的两个问题, 得到,要创建用户资源,客户端就向该帐户的uri发送put请求,因为uri是由客户端负责决定的。

客户端将修改这些资源吗?

起码用户密码是应该被客户修改的。

客户端将删除这些资源吗 ?

 当帐户不用的时候,允许用户将其删除

客户端将获取这种资源的表示吗?

是的。 也许可以用它来检查某个用户名是否已被占用。

五 设计来自客户端的表示

也就是说,客户端应该如何来创建一个用户帐户。

此时用户名已经作为uir里的作用域信息了,密码放哪里 ?

客户端会把密码作为资源表示放在实体主体里发送过去。客户端应该采用什么格式来表达新的资源状态。假如资源状态比较复杂,那么采用服务器发给客户端时采用的格式比较好。客户端通过GET请求从服务端得到一个表示,然后修改其表示,在通过PUT请求发回给客户端。作者采用表单编码格式(媒体类型application/x-www-form-urlencoded)来作为表示格式。 

六  设计发给客户端的表示

要注意的是,这里的密码, 是不能发到客户端的。 所以需要根据具体的情况,来设计发给客户端的表示。

七  把该资源与现有资源链接起来

作者举了两个例子, 我只说一个。 上一章里作者为地图服务定义了很多资源,比如星球列表。 如何链接呢, 对于未注册的用户,当他get回一个星球列表资源来,可以看到超媒体表示-注册用户的链接。

八  会由哪些典型事件经过

此时可能会有客户端向/user/blackanger发送put请求,将发生什么 ?我需要决定,为返回的响应设置什么响应代码,应提供什么http报头和实体主体,该请求如何影响资源状态。

九 可能出现哪些错误情况

考虑到一些可能出现的错误情况,设置响应代码。例子看书P156

自定义地点

于这个资源, 又要重复一遍上述的设计步骤。 但是这个资源类型和用户帐号资源有不同,这是一个从属资源。可以去看书P157,这里不做记录。

下一章,也就是第七章,有一个具体的实践, 继续重复上述步骤,不过起码可以通过代码看到一个具体到服务的实现了。

我来说两句:

看完本章作者把用户帐户作为一个资源, 结合以往几章的种种, 不禁要想,登陆这个操作,并不属于HTTP统一接口里的方法,按面向资源的设计,登陆这个要抽象为一个对象,也就是登陆也就是一个资源了。 让我们来看看Rails插件 restful_authentication就是遵循了这个原则。 

有一个session_controller.rb, rails里controller表示的是资源(我发明的土话)。用户登陆, session里保存用户状态,那么相当于给sessoin这个资源里创建一个子资源。 只要往这里发送put请求就行了。来看看routes设置:

map.logout '/logout', :controller => 'sessions', :action => 'destroy'

map.login '/login', :controller => 'sessions', :action => 'new'

登陆就是new一个session对象, 注销就是把这个对象删除了。很自然明了。

让我们来看看生成的表单:

<form method="post" action="/session">

     ...    ...

</form>

这里的http方法应该是PUT的呀, 可是为什么会是POST呢?引用DHH的话来说明:

“这个表单的action不是一个常规的POST方法,而是一个PUT。这里展示的是这个操作应该的模样。如果HTML表单支持PUT方法的话,我们本该这样写来着。很不幸,事实并非如此(HTML表单不支持PUT action),所以我们只能用POST来伪造一个PUT。在Rails中,当你这样写的时候,产生出来的表单里包含了一个隐藏的域,称为 underscored method(下划线方法),这个下划线方法会去调用真正干事的那个方法。我们这么做就能让Rails相信,这个POST实际上是个PUT”

下一章,也就是第七章,有一个具体的Rails实践, 继续重复上述步骤,不过起码可以通过代码看到一个具体到服务的实现了。

to be continued ... ...

 

©著作权归作者所有:来自51CTO博客作者blackanger的原创作品,如需转载,请注明出处,否则将追究法律责任

rubyservicesweb

0


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消