Django教程: 支持HTTPS访问及Nginx配置SSL证书
什么是HTTPS?简单来说:HTTPS = HTTP + SSL / TLS也就是在HTTP(超文本传输协议)上又加了一层处理加密信息的模块。服务端和客户端的信息传输都会通过TLS进行加密,所以传输的数据都是加密后的数据。HTTPS (全称:Hyper Text Transfer Protocol over SecureSocket Layer),即安全套接字层超文本传输协议,它是以安全为目标的
什么是HTTPS?
简单来说:HTTPS = HTTP + SSL / TLS
也就是在HTTP(超文本传输协议)上又加了一层处理加密信息的模块。服务端和客户端的信息传输都会通过TLS进行加密,所以传输的数据都是加密后的数据。
HTTPS (全称:Hyper Text Transfer Protocol over SecureSocket Layer),即安全套接字层超文本传输协议,它是以安全为目标的 HTTP 通道,在HTTP的基础上通过传输加密和身份认证保证了传输过程的安全性。HTTPS 在HTTP 的基础下加入SSL 层,HTTPS 的安全基础是 SSL,因此加密的详细内容就需要 SSL。 HTTPS 存在不同于 HTTP 的默认端口及一个加密/身份验证层(在 HTTP与 TCP 之间)。
注意:HTTP协议
默认使用的是80端口,而HTTPS协议
默认使用的是443端口。
获取SSL证书
SSL证书,通常包括一张证书(.cert或.pem)和一个私有密钥文件(.key)。
SSL证书分很多类型,贵的都是高级别的HTTPS证书,比如EV证书。免费的HTTPS证书是低级别的证书,如DV证书,DV证书只验证域名所有权,且功能有限制,支持单个或者少数几个域名,所以免费。个人站长可以申请免费SSL证书来用,成本低,也能起到加密作用。
其实免费的SSL证书阿里云、腾讯云、Lets Encrypt、freessl等等都有,足够个人网站使用。以阿里云举例
购买证书
配置nginx
将获取到的证书和密钥上传到服务器的任何一个指定目录,如我的在下面是基本配置
server {
listen 443 ssl; # 端口
server_name blog.zhwei.cn; # 域名
ssl_certificate /etc/nginx/cert/fullchain.crt; # 证书
ssl_certificate_key /etc/nginx/cert/privkey.key; # 密钥
}
Django
部署时以Nginx
做反向代理和静态文件服务器,这里以基于 Docker 的 Django 容器化部署教程为例进行配置
nginx配置
server {
listen 443 ssl;
server_name blog.zhwei.cn; # 域名
ssl on;
ssl_certificate /etc/nginx/cert/fullchain.crt;
ssl_certificate_key /etc/nginx/cert/privkey.key;
ssl_ciphers TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+ECDSA+AES128:EECDH+aRSA+AES128:RSA+AES128:EECDH+ECDSA+AES256:EECDH+aRSA+AES256:RSA+AES256:EECDH+ECDSA+3DES:EECDH+aRSA+3DES:RSA+3DES:!MD5;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1d;
ssl_session_tickets on;
# 配置docker-compose.yml中挂载的 static
location /static/ {
autoindex on;
alias /opt/hw-blog/static/;
}
# 配置docker-compose.yml中挂载的 media
location /media/ {
autoindex on;
alias /opt/hw-blog/media/;
}
# 拦截所有请求 服务转发 端口需要一致
location / {
proxy_pass http://website:7000;
proxy_set_header Host $http_host; #header添加请求host信息
proxy_set_header X-Forwarded-Proto $scheme
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 增加代理记录
}
}
如果想http
请求永久地重定向至https
只需加上下面的内容
server {
listen 80;
server_name blog.zhwei.cn; # 域名
return 301 https://$host$request_uri;
}
docker-compose.yml
需要把证书目录映射
nginx:
image: nginx:latest
container_name: hw_nginx
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- ./django/static:/opt/hw-blog/static
- ./django/media:/opt/hw-blog/media
- ./nginx:/etc/nginx/conf.d
- /opt/ssl/blog.zhwei.cn:/etc/nginx/cert # 证书目录
depends_on:
- website
networks:
- django_network
配置Django支持https
给Django
网站和用户数据提供更高级别的保护,需要在settings.py
新增如下安全配置
# SECURITY安全设置 - 支持http时建议开启
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") # 推荐
SECURE_SSL_REDIRECT = True # 将所有非SSL请求永久重定向到SSL
SESSION_COOKIE_SECURE = True # 仅通过https传输cookie
CSRF_COOKIE_SECURE = True # 仅通过https传输cookie
SECURE_HSTS_INCLUDE_SUBDOMAINS = True # 严格要求使用https协议传输
SECURE_HSTS_PRELOAD = True # HSTS为
SECURE_HSTS_SECONDS = 60
SECURE_CONTENT_TYPE_NOSNIFF = True # 防止浏览器猜测资产的内容类型
还有一种方法,但是我没有尝试
Django
的SECURE_SSL_REDIRECT = True
也可实现80端口的http
请求永久地重定向至https
, 与Nginx
的301重定向设置选其一即可。Django
以上的几个安全设置均依赖下面这个SecurityMiddleware
中间件。
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
]
这时候如果在模板中使用{{ request.build_absolute_uri }}
即可自动识别https
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)