第五章 IRIS 修改规范类

本章总结了如何以及为什么修改REST服务的规范类。

本章假设您以前已经生成了REST服务类,如“创建和编辑REST服务”中所述。

5.1 概述

下表列出了修改规范类的原因,并简要总结了所需的更改:

原因变化
更新或替换规范手动或通过重新生成规范类来修改OpenAPI XData块。
启用REST服务以支持CORS手动修改OpenAPI XData块;还添加一个类参数并创建一个自定义分派超类。请参阅“在REST服务中支持CORS”
启用REST服务以支持web会话添加类参数。请参阅“将Web会话用于REST”一章
指定使用端点所需的权限手动修改OpenAPI XData块。请参阅“保护REST服务”一章
重写默认内容类型、响应字符集或输入流处理添加类参数。请参阅本章下一节。
为服务方法指定非默认名称手动修改OpenAPI XData块。请参阅本章中的“重写服务方法的名称”。

每当编译规范类时,编译器都会在同一个包中重新生成分派类并更新实现类(请参阅“InterSystems如何更新实现类”)。

5.2 覆盖内容类型、响应字符集或输入流处理

只需向规范类添加类参数并重新编译,就可以覆盖REST服务的几个关键方面。

  • 默认情况下,REST服务需要application/json内容类型。要覆盖此项,请将以下内容添加到规范类:
Parameter CONTENTTYPE = "some-content-type";

其中some-content-type是MIME内容类型。

  • 默认情况下,REST服务的响应消息采用UTF-8格式。要覆盖此项,请将以下内容添加到规范类:
Parameter CHARSET = "some-character-set";

这里some-character-set是字符集的名称。

  • 默认情况下,REST服务将输入字符流转换为Unicode。要不执行此操作,请将以下内容添加到规范类中:
Parameter CONVERTINPUTSTREAM = 0";

然后重新编译。然后将这些更改复制到分派类。

5.3 重写服务方法的名称

默认情况下,编译器使用操作的operationId来确定相应REST调用调用的方法的名称。您可以指定其他名称。为此,在规范类的OpenAPI XData块中添加以下操作:

"x-ISC_ServiceMethod":"alternatename"

例如:

    "/pets":{
      "get":{
        "description":"Returns all pets from the system that the user has access to",
        "operationId":"findPets",
        "x-ISC_ServiceMethod":"ReturnPets",
        "produces":[
          "application/json",
          "application/xml",
          "text/xml",
          "text/html"
        ],

然后重新编译。然后编译器将这个新方法添加到分派和实现类中。一定要编辑实现类并为这个新方法提供一个实现。

5.4 在REST服务中支持CORS

跨源资源共享(CORS)允许在另一个域中运行的脚本访问服务。

通常,当浏览器从一个域运行脚本时,它允许对同一域进行XMLHttpRequest调用,但在对另一个域进行调用时不允许。这种浏览器行为限制某人创建恶意脚本,以滥用机密数据。恶意脚本可能允许用户使用授予用户的权限访问另一个域中的信息,但随后,在用户未知的情况下,对机密信息进行其他使用。为了避免这个安全问题,浏览器通常不允许这种跨域

如果不使用跨源资源共享(CORS),带有访问REST服务的脚本的网页通常必须与提供REST服务的服务器位于同一域中。在某些环境中,在不同于提供REST服务的服务器的域中使用脚本的网页是有用的。CORS支持这种安排。

下面提供了浏览器如何使用CORS处理XMLHttpRequest的简化描述:

  1. DomOne中网页中的脚本包含对域DomTwo中的InterSystems IRIS REST服务的XMLHttpRequestXMLHttpRequest具有CORS的自定义标头。
  2. 用户查看此网页并运行脚本。用户的浏览器检测到与包含网页的域不同的域的XMLHttpRequest
  3. 用户的浏览器向InterSystems IRIS REST服务发送一个特殊请求,该请求指示XMLHttpRequest的HTTP请求方法和原始网页的域,在本例中为DomOne
  4. 如果请求被允许,则响应包含请求的信息。否则,响应仅包含指示CORS不允许请求的标头。

5.4.1 启用REST服务以支持COR概述

默认情况下,InterSystems REST服务不允许CORS标头。但是,您可以启用CORS支持。在REST服务中支持CORS有两个部分:

  • 启用REST服务以接受部分或所有HTTP请求的CORS标头。请参阅“接受CORS标题”
  • 编写代码,使REST服务检查CORS请求并决定是否继续。例如,您可以提供包含仅包含受信任脚本的域的允许列表。InterSystems IRIS为文档目的提供了一个简单的默认实现;此默认实现允许任何CORS请求。

重要:

默认的CORS标头处理不适用于处理机密数据的REST服务。

5.4.2 接受CORS 标头

要指定REST服务接受CORS标头,请执行以下操作:

  1. 修改规范类以包含HandleCorsRequest参数。

    要为所有调用启用CORS标头处理,请将HandleCorsRequest参数指定为1:

    Parameter HandleCorsRequest = 1;
    

    或者,要为某些调用而不是调用启用CORS标头处理,请将HandleCorsRequest参数指定为""(空字符串):

    Parameter HandleCorsRequest = "";
    
  2. 如果将HandleCorsRequest参数指定为"",请编辑规范类中的OpenAPI XData块,以指示哪些调用支持CORS。具体来说,对于操作对象,添加以下属性名称和值:

    "x-ISC_CORS":true
    

    例如,OpenAPI XData块可能包含以下内容:

    "post":{
      "description":"Creates a new pet in the store.  Duplicates are allowed",
      "operationId":"addPet",
      "produces":[
        "application/json"
      ],
      ...
    
    

    添加x-ISC_CORS属性,如下所示:

    "post":{
      "description":"Creates a new pet in the store.  Duplicates are allowed",
      "operationId":"addPet",
      "x-ISC_CORS":true, 
      "produces":[
         "application/json"
      ],
      ...
    
    
  3. 编译规范类。此操作将重新生成分派类,从而导致行为的实际更改。无需详细了解分派类,但请注意以下更改:

    • 它现在包含HandleCorsRequest参数的值。
    • URLMapXData块现在包含与您修改的操作相对应的<Route>元素的Cors=“true”

如果HandleCorsRequest参数为0(默认值),则对所有调用禁用CORS标头处理。在这种情况下,如果REST服务接收到带有CORS标头的请求,则该服务拒绝该请求。

重要:

InterSystems IRIS REST服务支持OPTIONS请求(CORS预飞行请求),该请求用于确定REST服务是否支持CORS。发送此类请求的用户应该对REST服务使用的任何数据库具有READ权限。如果没有,服务将响应HTTP 404错误。在使用委托身份验证的配置中,请求将由经过身份验证的用户发送;在ZAUTHENTICATE例程中分配适当的权限。在不使用委托身份验证的配置中,此请求未经身份验证发送,并由CSPSystem用户执行;使用管理门户分配适当的权限。

5.4.3 定义如何处理CORS标头

当您启用REST服务接受CORS标头时,默认情况下,该服务接受任何CORS请求。REST服务应该检查CORS请求并决定是否继续。例如,您可以提供包含仅包含受信任脚本的域的允许列表。为此,您需要:

  • 创建%CSP.REST的子类。在该类中,实现第一小节中描述的OnHandleCorsRequest()方法。
  • 修改规范类并重新编译,重新生成分派类。

最终结果是分派类继承自您的自定义类,而不是%CSP.REST,因此使用了OnHandleCorsRequest()的定义,该定义覆盖了默认的CORS头处理。

5.4.3.1 定义OnHandleCorsRequest()

%CSP.REST的子类中,定义OnHandleCorsRequest()方法,该方法需要检查CORS请求并适当设置响应标头。

要定义此方法,您必须熟悉CORS协议的详细信息(此处未讨论)。

您还需要知道如何检查请求并设置响应标头。为此,检查默认使用的方法是有用的,%CSP.RESTHandleDefaultCorsRequest()方法。本节介绍了该方法如何处理源、凭据、头和请求方法,并提出了一些变化。您可以使用此信息编写OnHandleCorsRequest()方法。

以下代码获取源并使用它设置响应标头。一种可能的变化是根据允许列表测试原点。然后允许域,设置响应标头。如果没有,请将响应标头设置为空字符串。

#; Get the origin
Set tOrigin=$Get(%request.CgiEnvs("HTTP_ORIGIN"))

#; Allow requested origin
Do ..SetResponseHeaderIfEmpty("Access-Control-Allow-Origin",tOrigin) 

以下行指定应包含授权标头。

#; Set allow credentials to be true
Do ..SetResponseHeaderIfEmpty("Access-Control-Allow-Credentials","true")

以下行从传入请求中获取标头和请求方法。您的代码应该测试头和请求方法是否被允许。如果允许,请使用它们设置响应标头。如果没有,请将响应标头设置为空字符串。

#; Allow requested headers
Set tHeaders=$Get(%request.CgiEnvs("HTTP_ACCESS_CONTROL_REQUEST_HEADERS"))
Do ..SetResponseHeaderIfEmpty("Access-Control-Allow-Headers",tHeaders)

#; Allow requested method
Set tMethod=$Get(%request.CgiEnvs("HTTP_ACCESS_CONTROL_REQUEST_METHOD"))
Do ..SetResponseHeaderIfEmpty("Access-Control-Allow-Method",tMethod)

重要:

默认的CORS标头处理不适用于处理机密数据的REST服务。

5.4.3.2 修改规范类

在包含OnHandleCorsRequest()%CSP.REST的自定义子类后,请执行以下操作:

  1. 编辑规范类中的OpenAPI XData块,使信息对象包含名为x-ISC_DispatchParent的新属性。此属性的值必须是自定义类的完全限定名称。

    例如,假设OpenAPI XData块如下所示:

      "swagger":"2.0",
      "info":{
        "version":"1.0.0",
        "title":"Swagger Petstore",
        "description":"A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification",
        "termsOfService":"http://swagger.io/terms/",
        "contact":{
          "name":"Swagger API Team"
        },
    ...
    

    假设%CSP.REST的自定义子类名为test.MyDispatchClass。在这种情况下,您将按如下方式修改XData块:

      "swagger":"2.0",
      "info":{
        "version":"1.0.0",
        "title":"Swagger Petstore",
        "description":"A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification",
        "termsOfService":"http://swagger.io/terms/",
        "x-ISC_DispatchParent":"test.MyDispatchClass",
        "contact":{
          "name":"Swagger API Team"
        },
    ...
    
  2. 编译规范类。此操作重新生成调度类。您将注意到该类现在扩展了您的自定义分派超类。因此,它将使用OnHandleCorsRequest()方法。

5.5 将Web会话与REST结合使用

REST的目标之一是无状态;也就是说,从一个REST调用到下一个调用,服务器上没有存储任何知识。跨REST调用保留web会话打破了无状态范式,但您可能希望保留web会话的原因有两个:

  • 最小化连接时间-如果每个REST调用都创建一个新的web会话,则需要在服务器上建立一个新会话。通过保留web会话,REST调用连接速度更快。
  • 跨REST调用保留数据-在某些情况下,跨REST调用保存数据可能是有效满足业务需求所必需的。

要启用在多个REST调用上使用单个web会话,请在规范类中将UseSession参数设置为1。例如:

Parameter UseSession As Integer = 1;

然后重新编译这个类。

如果UseSession为1,则InterSystems IRIS将在多个REST服务调用之间保留web会话。如果参数为0(默认值),InterSystems IRIS将为每个REST服务调用使用新的web会话。

注:

重新编译规范类时,UseSession参数会复制到分派类,这会导致行为的实际变化。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值