一位同事build议我把这个从StackOverflow重新发布到ServerFault:
这一直使我疯狂。 我有一个通过Apache Web服务器提供的Web应用程序。 支持应用程序的数据库服务器是Apache CouchDB,它公开了HTTP API来检索文档和stream附件。
我通过提供一个安全对象来保护CouchDB数据库,该安全对象只允许某些用户访问数据库中的数据,并返回401匿名请求到HTTP端点。
我想能够映射公共URL到存储在这个数据库中的文档附件。 所以,我试图在我的.htaccess文件中创build一个重写规则,它将来自某些URL的请求直接代理到CouchDB,同时对用户凭证进行硬编码,如下所示:
## DOWNLOAD STREAM: RewriteCond %{HTTP_HOST} ^example.com$ RewriteRule download/(.*) http://user:[email protected]:5984/database/$1 [P]
在理想的世界中,上面的例子将采用以下URL:
http://example.com/download/UUID/attachment.ext
并代理它:
http://user:[email protected]:5984/database/UUID/attachment.ext
这个方法确实将请求代理到CouchDB,但省略了URIscheme的userinfo组件。 所以,该请求被视为匿名,我得到一个401错误。 如果从数据库中删除安全性,附件只能stream式传输。
我花了几个小时阅读Apache的configuration和尝试无济于事。 由于所有相关的查询都有类似的关键字,networkingsearch是徒劳的。
我如何确保mod_rewrite包含在代理CouchDB时在重写规则中提供的用户名和密码?
我想到了! 授权标头需要独立设置,而不是将用户名:密码作为URIscheme的一部分。 以下解决scheme完全在.htaccess文件中工作,这一点很重要,因为OS X会定期吹走VirtualHost站点中的设置:
SetEnvIf Request_URI ^/download/* ADD_COUCH_BASIC_AUTH RequestHeader set Authorization "Basic XXXXXXXXXXXX" env=ADD_COUCH_BASIC_AUTH ## DOWNLOAD STREAM RewriteCond %{HTTP_HOST} ^example.com$ RewriteRule download/(.*) http://127.0.0.1:5984/database/$1 [P]
这样做的方式:我们使用SetEnvIf检查请求path是否匹配我们想要代理的path,如果是,请设置一个任意的环境variablesADD_COUCH_BASIC_AUTH
在随后的行中, 只有当我们设置的环境variables存在时, 才会向传出请求添加一个Basic Auth头。 所以,只有在通过/download/请求资源时才会添加基本的auth头,从而将身份validation凭证发送到CouchDB。
注意:您必须对您的用户名:密码凭据进行Base64编码,并用编码值replaceXXXXXXXXXXX 。 一个简单的方法来做到这一点,在Mac上:
echo -n 'user:pass' | openssl base64
希望这有助于除了我之外的人!