我正在使用Clojure(ring和compojure)来构建一个Web应用程序,我不知道从哪里开始使用https。我有一个需要保护的注册和登录,然后一旦他们通过身份验证,他们就需要保持https状态。
我似乎找不到一个关于一般设置https或专门设置clojure应用程序的好教程。
我找到了这个答案:How do you enable https and http->https redirects in ring / compojure
这是否意味着我可以编写我的compojure应用程序,好像没有https并且让nginx坐在前面并为我处理所有这些?
答案 0 :(得分:7)
是的,标准程序是让nginx在基于环网的webapp前面充当 reverse proxy 。这被认为是安全的,并且更容易维护,因为它更标准。我知道的每个clojure based site都是这样做的。
答案 1 :(得分:3)
通常,应用程序级代码不关心它是HTTPS还是HTTP。大多数情况下,它由应用程序服务器或其前面的代理提供。如果您熟悉,您的选择与Java世界中的选择非常相似。
如果您正在使用Jetty适配器,它有ssl?
和ssl-port
个选项。请参阅docs here和related blog post here。
您可以在纯HTTP中运行您的Ring应用程序,并在其前面放置一个代理,如Nginx或Apache。代理将实现HTTPS并将请求作为普通HTTP转发到您的应用程序。
答案 2 :(得分:3)
反向代理方法似乎确实是最常见的选择。然而,作为一个“实验”,我研究了使用https来使用ring,jetty compojure等。这并不难。
首先,您需要使用keytool生成自签名证书并将其安装到新的密钥库中。 keytool文档非常好,可以引导您完成此过程。请注意,如果您使用自签名证书,则需要为大多数浏览器添加例外规则,以表明您信任该证书。
将创建的密钥库文件复制到项目树的根目录
更新jetty配置参数以指定ssl,ssl-port,密钥库文件和密钥库密码。
将ring / ring-defaults包添加到project.clj
使用secure-site-defaults配置选项添加wrap-defaults中间件以强制https连接,即将http连接重定向到https。
这不是我建议用于生产的设置,但我发现它比在开发等时配置ngix更简单。最难的部分是通过keytool进程。但是,只需按照文档和示例提供的内容就足够了,只要您不允许yoruself被所有选项所淹没 - 只需保持简单。
像
这样的东西keytool -genkeypair \
-keystore $SSL_DIR/$KS_NAME \
-keypass $PASSWORD \
-storepass $PASSWORD \
-keyalg RSA -keysize 2048 \
-alias root \
-ext bc:c \
-dname "$ROOT_CN"
echo "CA Key"
keytool -genkeypair \
-keystore $SSL_DIR/$KS_NAME \
-alias ca \
-ext bc:c \
-keypass $PASSWORD \
-keyalg RSA -keysize 2048 \
-storepass $PASSWORD \
-dname "$CA_CN"
echo "Server Key"
keytool -genkeypair \
-keystore $SSL_DIR/$KS_NAME \
-alias server \
-keypass $PASSWORD \
-storepass $PASSWORD \
-keyalg RSA -keysize 2048 \
-dname "$SERVER_CN"
echo "Root Cert"
keytool -keystore $SSL_DIR/$KS_NAME \
-storepass $PASSWORD \
-alias root \
-exportcert \
-rfc > $SSL_DIR/root.pem
echo "CA Cert"
keytool -storepass $PASSWORD \
-keystore $SSL_DIR/$KS_NAME \
-certreq \
-alias ca | keytool -storepass $PASSWORD \
-keystore $SSL_DIR/$KS_NAME \
-gencert \
-alias root \
-ext BC=0 \
-rfc > $SSL_DIR/ca.pem
echo "Import CA cert"
keytool -keystore $SSL_DIR/$KS_NAME \
-storepass $PASSWORD \
-importcert \
-alias ca \
-file $SSL_DIR/ca.pem
echo "Server Cert"
keytool -storepass $PASSWORD \
-keystore $SSL_DIR/$KS_NAME \
-certreq \
-alias server | keytool -storepass $PASSWORD \
-keystore $SSL_DIR/$KS_NAME \
-gencert \
-alias ca \
-rfc > $SSL_DIR/server.pem
echo "Import Server Cert"
cat $SSL_DIR/root.pem $SSL_DIR/ca.pem $SSL_DIR/server.pem | \
keytool -keystore $SSL_DIR/$KS_NAME \
-storepass $PASSWORD \
-keypass $PASSWORD \
-importcert \
-alias server
答案 3 :(得分:1)
另一个解决方案是尝试使用nginx-clojure(http://nginx-clojure.github.io),您可以通过它直接在nginx上部署ring app。 nginx可以更有效地执行https操作。
以下是关于nginx.conf
的示例http {
### jvm dynamic library path
jvm_path '/usr/lib/jvm/java-7-oracle/jre/lib/amd64/server/libjvm.so';
### my app jars e.g. clojure-1.5.1.jar , groovy-2.3.4.jar ,etc.
jvm_var my_other_jars 'my_jar_dir/clojure-1.5.1.jar';
### my app classpath, windows user should use ';' as the separator
jvm_options "-Djava.class.path=jars/nginx-clojure-0.3.0.jar:#{my_other_jars}";
server {
listen 80 default deferred;
server_name example.com;
###redirect to https
rewrite ^/(.+) https://example.com/$1 permanent;
}
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /opt/mycert/my-unified.crt;
ssl_certificate_key /opt/mycert/my.key;
location /myapp {
content_handler_name 'my/ringapp';
}
}
}
您可以从http://nginx.org/en/docs/http/configuring_https_servers.html
获取有关SSL服务器配置的更多详细信息答案 4 :(得分:1)
非常简单。如果要在Web应用程序中启用HTTPS支持,请执行以下操作:
使用名为keytool的linux工具生成Java KeyStore(.jks)文件。
在project.clj文件的环形图中,添加以下内容:
{ :SSL?真正 :ssl-port 8443 :keystore“jks文件的路径” :密钥密码“密钥库密码” }
启动服务器。现在,您的网络应用已启用HTTPS。
当我尝试使用社交媒体代码测试我的登录时,我遇到了类似的问题,显然必须通过HTTPS进行身份验证,这对我来说很有用。
答案 5 :(得分:0)
您可以设置强制所有请求使用SSL的Ring中间件。一种简单的方法是使用ring-defaults库。
来自ring-defaults文档:
中间件包含四种配置 - api-defaults
- 网站默认值
- secure-api-defaults
- 安全站点默认值
...
“安全”默认强制SSL。未加密的HTTP URL被重定向到等效的HTTPS URL,并发送各种标头和标志,以防止浏览器通过不安全的通道发送敏感信息。
另请注意:
以下是一般概念:
(ns my-app
(:require [ring.middleware.defaults :refer :all]
[environ.core :refer [env]]))
(defroutes app-routes
(GET "/" [] "home page"))
(def app
(-> app-routes
(wrap-defaults (if (= (env :environment) "dev")
site-defaults
(assoc secure-site-defaults :proxy true))))
我不知道有关nginx的信息,但是我已经将其用于部署到Heroku的应用程序。