如何从 Jolie 服务的操作中设置 http cookies?

How to set http cookies from an operation of a Jolie service?

我需要通过 Jolie 服务的操作为浏览器设置 cookie,但我找不到有关如何操作的信息。

我查看了 https://jolielang.gitbook.io/docs/protocols/http and https://jolielang.gitbook.io/docs/web-applications/rest-apis-publication-and-integration 的文档,但似乎我提供的用例尚未涵盖。

inputPort MyIP {

    Protocol: http {
    ...
    ??? -> myCookie;
    ...
    }
    Interfaces: LoginInterface
}

main {

    [login(credentials)(res) {
    ...  
    myCookie=???  
    ...  
    }]
}

我希望在浏览器 cookie 存储中看到 cookie。

您的方向是正确的 cookie 的设置是通过使用 return Header 信息来执行的,如 MDN Reference 所示。

要在 Jolie 中操作响应 Header,您需要在 http 端口配置的 .addHeader 节点上工作 这是我的代码

interface MyInterface {

    RequestResponse:
     login(undefined)(undefined)
    }

    inputPort MyPort {
    Location: "socket://localhost:8000"
    Protocol: http {
      .debug= true;
      .debug.showContent= true;
      .addHeader.header[0] = "Set-Cookie";
      .addHeader.header[0].value->cookieCommand
    }
    Interfaces: MyInterface
    }

    execution{ concurrent }
    main{
      [login(request)(response){
          //doing something to control my credatiol
          cookieCommand = "yummy_cookie=myCookieValue "
        }]
    }  

你如何阅读这段代码

  .addHeader.header[0] = "Set-Cookie";
  .addHeader.header[0].value->cookieCommand

这部分将 header 添加到响应 "Set-Cookie" header 中,它将具有变量 cookieCommand 的值;符号 -> 是 structure alias

现在你的变量cookieCommand可以设置在任何操作行为中,在我的例子中是在登录操作中

      [login(request)(response){
          //doing something to control my credatiol
          cookieCommand = "yummy_cookie=myCookieValue "
        }]

调用结果如下图

这是浏览器上的结果

现在让我们看看如何处理传入的cookie。首先,我们可以定义一个新的操作op1

interface MyInterface {
RequestResponse:
 login(undefined)(undefined),
 op1(op1RequestType)(op1ResponseType)
}

在请求类型中,我们需要添加一个包含我们的应用程序 cookie 值的新节点

type op1RequestType:void{
  .cookieValue:string
}

然后我们需要设置Http inputPort接收到的cookie值与操作输入变量的匹配

inputPort MyPort {
Location: "socket://localhost:8000"
Protocol: http {
  .debug= true;
  .debug.showContent= true;
  .addHeader.header[0] = "Set-Cookie";
  .addHeader.header[0].value->cookieCommand;
  .osc.op1.cookies.yummy_cookie = "cookieValue"
}
Interfaces: MyInterface
}

端口配置参数

.osc.op1.cookies.yummy_cookie = "cookieValue"

读作 osc.(nameOperation).cookies.nameCookie = nameNodeInTheType

让我们看看来自浏览器的调用

和来自操作的跟踪 (jolie --trace)

希望对您有所帮助

读取和写入 cookie

您可以使用 cookies 参数,它将 cookie 名称映射到消息中存在的字段。

例如,.cookies.auth_token = "token" 将名为 auth_token 的 cookie 绑定到消息中的字段 token(读取和写入)。

这是一个完整的示例,其中 login 操作在浏览器中设置 cookie auth_token

execution { concurrent }

inputPort Server {
Location: "socket://localhost:8080"
Protocol: http
  // Binds the cookie "auth_token" to the message field "token"
  { .cookies.auth_token = "token" }
RequestResponse: login
}

main
{
  login( request )( response ) {
    if ( request.pwd == "secret" )
      response << "OK" { .token = new }
    else
      response << "Invalid pwd" { .token = "" }
  }
}

您可以浏览http://localhost:8080/login?pwd=secret.

试一试

奖励:带有相关集的 cookie

像这样使用 cookie 可以将它们与工作流程结合起来,以进行编程 process-aware web applications。这是一个更详细的示例,其工作流程如下:

  1. 用户登录;
  2. 如果登录成功,可以随意调用操作say,直到调用操作logout
  3. 用户注销。

我正在使用下面的相关集来跟踪会话。

include "console.iol"

execution { concurrent }

type LoginRequest:void { .token?:string .pwd:string }
type TokenMessage:void { .token:string }
type SayRequest:void { .token:string .msg:string }

interface ServerIface {
RequestResponse:
  login(LoginRequest)(TokenMessage) throws InvalidPwd,
  say(SayRequest)(void),
  logout(TokenMessage)(TokenMessage)
}

inputPort Server {
Location: "socket://localhost:8080"
Protocol: http { .cookies.auth_token = "token" }
Interfaces: ServerIface
}

cset {
  token: SayRequest.token TokenMessage.token
}

main
{
  login( request )( response ) {
    if ( request.pwd == "secret" )
      response.token = csets.token = new
    else
      throw( InvalidPwd )
  };
  provide
    [ say( request )() {
      println@Console( csets.token + " says " + request.msg )()
    } ]
  until
    [ logout()( response ) { response.token = "" } ]
}

要尝试,您可以导航到这些链接(按顺序):

  1. http://localhost:8080/login?pwd=secret
  2. http://localhost:8080/say?msg=Hello
  3. http://localhost:8080/logout

参考文献: