如何从 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。这是一个更详细的示例,其工作流程如下:
- 用户登录;
- 如果登录成功,可以随意调用操作
say
,直到调用操作logout
;
- 用户注销。
我正在使用下面的相关集来跟踪会话。
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 = "" } ]
}
要尝试,您可以导航到这些链接(按顺序):
- http://localhost:8080/login?pwd=secret
- http://localhost:8080/say?msg=Hello
- http://localhost:8080/logout
参考文献:
- 会话和相关集:https://jolielang.gitbook.io/docs/basics/sessions
- provide-until 语句:https://jolielang.gitbook.io/docs/basics/composing_statements#the-provide-until-statement
- Jolie 关于 provide-until 和网络工作流的论文:https://doi.org/10.1016/j.scico.2016.05.002 (open version: https://arxiv.org/abs/1410.3712)
我需要通过 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。这是一个更详细的示例,其工作流程如下:
- 用户登录;
- 如果登录成功,可以随意调用操作
say
,直到调用操作logout
; - 用户注销。
我正在使用下面的相关集来跟踪会话。
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 = "" } ]
}
要尝试,您可以导航到这些链接(按顺序):
- http://localhost:8080/login?pwd=secret
- http://localhost:8080/say?msg=Hello
- http://localhost:8080/logout
参考文献:
- 会话和相关集:https://jolielang.gitbook.io/docs/basics/sessions
- provide-until 语句:https://jolielang.gitbook.io/docs/basics/composing_statements#the-provide-until-statement
- Jolie 关于 provide-until 和网络工作流的论文:https://doi.org/10.1016/j.scico.2016.05.002 (open version: https://arxiv.org/abs/1410.3712)