通过域名(而非 IP)访问服务器时,用户会话未保留在 eXist-db 中
User session not preserved in eXist-db when the server is accessed via domain name (not IP)
我正在尝试为实际生产环境配置我的 eXist-db 应用程序。这意味着使用域名而不是 localhost
或 IP 地址。当我通过纯 IP 访问服务器时,一切正常。当我通过域名访问它时,我只能按页面登录。我登录后,一旦尝试访问应用程序页面上的另一个 link(或当前的!再次),我就会退出。
我的控制器:
xquery version "3.0";
import module namespace login="http://exist-db.org/xquery/login" at "resource:org/exist/xquery/modules/persistentlogin/login.xql";
declare variable $exist:path external;
declare variable $exist:resource external;
declare variable $exist:controller external;
declare variable $exist:prefix external;
declare variable $exist:root external;
declare variable $local:login_domain := 'domain-x';
let $set-user := login:set-user($local:login_domain, (), false())
(: Here we are grabbing all names of user's groups. :)
let $user := request:get-attribute('domain-x.user')
let $groups := if ($user) then string-join(sm:get-user-groups($user), ', ') else 'NoGroup'
return
if ($exist:path eq '/'or $exist:resource eq 'index.html') then
<dispatch xmlns='http://exist.sourceforge.net/NS/exist'>
<forward url='{$exist:controller}/index.html'/>
<view>
<forward url="{$exist:controller}/modules/view.xql"/>
</view>
<error-handler>
<forward url="{$exist:controller}/error-page.html" method="get"/>
<forward url="{$exist:controller}/modules/view.xql"/>
</error-handler>
</dispatch>
else if (
($exist:path eq '/create-ebooks-search.html') or
($exist:path eq '/create-ebooks-list.html') or
($exist:path eq '/metadata-tool.html') or
($exist:path eq '/testing.html') or
($exist:path eq '/create-ejournals-list.html')
)
then
if (contains($groups, 'editors')) then
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
<!-- All sites are placed in the 'secure' directory,
links to them are as if they were in the root of the app,
hence the forwarding. -->
<forward url='{$exist:controller}/secure/{$exist:resource}'/>
<view>
<forward url="{$exist:controller}/modules/view.xql">
<set-attribute name="hasAccess" value="true"/><!-- Only for reference -->
<set-attribute name="$exist:prefix" value="{$exist:prefix}/secure"/>
<set-attribute name="$exist:controller" value="{$exist:controller}"/>
<!-- This is very important, without this or similar header, authentication
does not work properly—login and logout does not work as expected,
on some sites is is detected by the template, on some it is not.
It is possible to use other headers, works as well:
private, no-store, max-age=0, no-cache, must-revalidate are useful.
It is necessary to use it for the forward action of the view. -->
<set-header name="Cache-Control" value="no-cache"/>
</forward>
</view>
<error-handler>
<forward url="{$exist:controller}/error-page.html" method="get"/>
<forward url="{$exist:controller}/modules/view.xql"/>
</error-handler>
</dispatch>
...
更新
好像跟cookies有关。如果我尝试登录通过 IP 地址访问的页面,则会存储一个名为 org.exist.login
的 cookie,并在该站点的页面之间传递。如果我尝试登录通过域名访问的页面,则cookie丢失。
更新二
我通过 Redbird 代理,我的配置:
var proxy = require('redbird')({
port:80,
ssl: {
port: 443
}
});
proxy.register('my-app.domain.com', 'http://xx.xx.xxx.xxx:8081/exist/apps/my-app', {
ssl: {
key: '../SSL-certs/dev-key.pem',
cert: '../SSL-certs/dev-cert.pem',
}
});
(我无法使用 中描述的 letsencrypt。)
我认为这确实是一个 Redbird 问题,与 Redbird 是否将主机名传递给 eXist 并允许 eXist 的 set-cookie header 将此主机名返回给客户端有关。为了比较,请参阅 history.state.gov 的 nginx 是如何配置的 - https://github.com/HistoryAtState/hsg-project/blob/master/deploy/1861/etc/nginx/vhosts/1861.hsg.conf#L22-L24:
proxy_pass_header Set-Cookie;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
请参阅这篇文章,其中描述了仅使用 IP 与使用域时 cookie 的运行方式有何不同:How do browser cookie domains work?。
因为我没有使用过 Redbird,所以我无法提供准确的指导,但是如果您找不到 Redbird 与这些 nginx 指令的对应项,我建议您将您的问题作为关于 Redbird 的问题发布。
我正在尝试为实际生产环境配置我的 eXist-db 应用程序。这意味着使用域名而不是 localhost
或 IP 地址。当我通过纯 IP 访问服务器时,一切正常。当我通过域名访问它时,我只能按页面登录。我登录后,一旦尝试访问应用程序页面上的另一个 link(或当前的!再次),我就会退出。
我的控制器:
xquery version "3.0";
import module namespace login="http://exist-db.org/xquery/login" at "resource:org/exist/xquery/modules/persistentlogin/login.xql";
declare variable $exist:path external;
declare variable $exist:resource external;
declare variable $exist:controller external;
declare variable $exist:prefix external;
declare variable $exist:root external;
declare variable $local:login_domain := 'domain-x';
let $set-user := login:set-user($local:login_domain, (), false())
(: Here we are grabbing all names of user's groups. :)
let $user := request:get-attribute('domain-x.user')
let $groups := if ($user) then string-join(sm:get-user-groups($user), ', ') else 'NoGroup'
return
if ($exist:path eq '/'or $exist:resource eq 'index.html') then
<dispatch xmlns='http://exist.sourceforge.net/NS/exist'>
<forward url='{$exist:controller}/index.html'/>
<view>
<forward url="{$exist:controller}/modules/view.xql"/>
</view>
<error-handler>
<forward url="{$exist:controller}/error-page.html" method="get"/>
<forward url="{$exist:controller}/modules/view.xql"/>
</error-handler>
</dispatch>
else if (
($exist:path eq '/create-ebooks-search.html') or
($exist:path eq '/create-ebooks-list.html') or
($exist:path eq '/metadata-tool.html') or
($exist:path eq '/testing.html') or
($exist:path eq '/create-ejournals-list.html')
)
then
if (contains($groups, 'editors')) then
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
<!-- All sites are placed in the 'secure' directory,
links to them are as if they were in the root of the app,
hence the forwarding. -->
<forward url='{$exist:controller}/secure/{$exist:resource}'/>
<view>
<forward url="{$exist:controller}/modules/view.xql">
<set-attribute name="hasAccess" value="true"/><!-- Only for reference -->
<set-attribute name="$exist:prefix" value="{$exist:prefix}/secure"/>
<set-attribute name="$exist:controller" value="{$exist:controller}"/>
<!-- This is very important, without this or similar header, authentication
does not work properly—login and logout does not work as expected,
on some sites is is detected by the template, on some it is not.
It is possible to use other headers, works as well:
private, no-store, max-age=0, no-cache, must-revalidate are useful.
It is necessary to use it for the forward action of the view. -->
<set-header name="Cache-Control" value="no-cache"/>
</forward>
</view>
<error-handler>
<forward url="{$exist:controller}/error-page.html" method="get"/>
<forward url="{$exist:controller}/modules/view.xql"/>
</error-handler>
</dispatch>
...
更新
好像跟cookies有关。如果我尝试登录通过 IP 地址访问的页面,则会存储一个名为 org.exist.login
的 cookie,并在该站点的页面之间传递。如果我尝试登录通过域名访问的页面,则cookie丢失。
更新二
我通过 Redbird 代理,我的配置:
var proxy = require('redbird')({
port:80,
ssl: {
port: 443
}
});
proxy.register('my-app.domain.com', 'http://xx.xx.xxx.xxx:8081/exist/apps/my-app', {
ssl: {
key: '../SSL-certs/dev-key.pem',
cert: '../SSL-certs/dev-cert.pem',
}
});
(我无法使用
我认为这确实是一个 Redbird 问题,与 Redbird 是否将主机名传递给 eXist 并允许 eXist 的 set-cookie header 将此主机名返回给客户端有关。为了比较,请参阅 history.state.gov 的 nginx 是如何配置的 - https://github.com/HistoryAtState/hsg-project/blob/master/deploy/1861/etc/nginx/vhosts/1861.hsg.conf#L22-L24:
proxy_pass_header Set-Cookie;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
请参阅这篇文章,其中描述了仅使用 IP 与使用域时 cookie 的运行方式有何不同:How do browser cookie domains work?。
因为我没有使用过 Redbird,所以我无法提供准确的指导,但是如果您找不到 Redbird 与这些 nginx 指令的对应项,我建议您将您的问题作为关于 Redbird 的问题发布。