安全性
网站安全性是大课题。我这篇博文更多的是暴露问题,谋求解决方案。
一、API权限控制
初期项目的权限控制很简单,只需要控制如下情况即可:
1. 用户要创建自己的资源,需要用户的登录凭证。
2. 用户要修改、删除某个资源,或查看某个私有资源,需要用户的权限凭证。
关于以上两个,我在上一篇博文里提到过,使用require_login, require_permission的before_action回调解决。
在我的项目中,用户的凭证是通过传递Access-Token的Header来声明的。在Header中传递Token作为凭证,而不是通过参数传递,是不想污染参数的结构。Token的格式参考JWT。
另外,凭证传递我能叫得上的名字的有HTTP basic authentication,HTTP Digest authentication,OAuth,OAuth 2.0等方式。我只是知道或在某处看到过它们的名字而已,没有去了解过它们,并没有使用它们的任何一种。
二、SSL加强安全性
就像博文《Restful API设计最佳实践》中所说的,总是使用SSL。通过HTTP协议传递敏感数据,例如用户名和密码,是极不安全的。
我使用nginx作反向代理将HTTPS转化为HTTP代理给本地的Rails服务器,同时禁止本地Rails服务器对外访问,从而强制使用HTTPS协议。
events {} http { server { listen 443; ssl on; ssl_certificate certs/server.crt; ssl_certificate_key certs/server.key; gzip on; gzip_proxied any; gzip_types application/json; location / { proxy_pass http://localhost:3000; } } }
三、数据库安全
要为数据库配置用户名和密码,然后再对外网可见。不幸的是,Mongoid4.0版本并不支持MongoDB3.x的用户名和密码配置,因为MongoDB3.x升级了权限配置的方式。据说Mongoid5.0会修复这一问题,不过5.0正在开发中。这时,要么配置MongoDB仅对本地可见,要么配置iptables限制访问的ip。
#允许本地访问端口27017 iptables -A INPUT -s 127.0.0.1 -p tcp --destination-port 27017 -m state --state NEW,ESTABLISHED -j ACCEPT #允许指定ip访问端口27017 iptables -A INPUT -s <ip-address> -p tcp --destination-port 27017 -m state --state NEW,ESTABLISHED -j ACCEPT
#禁止其他的任何ip访问访问端口27017 iptables -A INPUT -p tcp --destination-port 27017 -j REJECT
四、密码HASH
不要明文存储用户密码。用hash,并且要用算法尽量慢的hash,如bcrypt,避免使用md5.
五、其他更多关于安全的问题
这个话题是说不尽的。