When developing applications with Facebook Login (or other OAuth providers), the HTTP Basic Authentication layer protecting your staging environment creates a significant roadblock. Facebook's servers need to access your callback URLs directly without authentication prompts, but you still want to maintain security for other visitors.
The most efficient solution is using Nginx's geo
module to create IP-based access rules. First, we need Facebook's current IP ranges:
# Facebook's IP ranges (updated as of 2023)
geo $auth_bypass {
default 0;
31.13.24.0/21 1;
31.13.64.0/18 1;
45.64.40.0/22 1;
66.220.144.0/20 1;
69.63.176.0/20 1;
69.171.224.0/19 1;
74.119.76.0/22 1;
102.132.96.0/20 1;
103.4.96.0/22 1;
129.134.0.0/16 1;
157.240.0.0/16 1;
173.252.64.0/18 1;
185.60.216.0/22 1;
204.15.20.0/22 1;
}
Combine this with Nginx's if
directive to create conditional authentication:
server {
listen 443 ssl;
server_name your-staging.example.com;
# Basic Auth for everyone except Facebook
if ($auth_bypass = 0) {
auth_basic "Restricted Access";
auth_basic_user_file /etc/nginx/.htpasswd;
}
location /facebook-callback {
# Facebook-specific handling
proxy_pass http://your_app_server;
}
}
For more complex scenarios, consider using the map
module:
map $remote_addr $auth_type {
default "Restricted Access";
"~^31\.13\." off;
"~^69\.171\." off;
# Add other Facebook IP patterns
}
server {
# ...
auth_basic $auth_type;
auth_basic_user_file /etc/nginx/.htpasswd;
}
Remember to:
- Regularly update Facebook's IP ranges (they change occasionally)
- Monitor your access logs for authentication failures from legitimate Facebook IPs
- Consider implementing a fail-safe mechanism that logs unexpected access attempts
Use curl
to verify from different IP perspectives:
# Should prompt for credentials
curl -v https://your-staging.example.com
# Should bypass auth (if using a Facebook IP proxy)
curl -v --proxy facebook-ip-proxy:port https://your-staging.example.com
When developing applications with third-party integrations like Facebook Login, HTTP Basic Authentication can block legitimate requests from the service's IP ranges. This creates a testing challenge where you want to protect your staging environment but still allow Facebook's servers to communicate with your endpoints.
The most efficient approach uses NGINX's geo
module to create conditional access rules. Here's how to implement it:
# In your http context (nginx.conf or included file)
geo $auth_bypass {
default 1;
31.13.0.0/16 0; # Facebook's primary IP range
157.240.0.0/16 0; # Additional Facebook IP range
129.134.0.0/16 0; # Instagram IPs (might use same infrastructure)
}
server {
listen 80;
server_name yourdomain.com;
location / {
auth_basic "Restricted Access";
auth_basic_user_file /etc/nginx/.htpasswd;
# Conditional auth bypass
if ($auth_bypass = 0) {
auth_basic off;
}
}
}
Facebook's IP ranges change occasionally. You should periodically check their official documentation or WHOIS records. A more dynamic approach would be:
geo $auth_bypass {
default 1;
include /etc/nginx/facebook_ips.conf;
}
Then maintain the IP ranges in a separate file that you can update independently.
For more complex scenarios, the map
directive offers additional flexibility:
map $remote_addr $auth_type {
default "Restricted Access";
31.13.0.0/16 off;
157.240.0.0/16 off;
}
server {
# ...
auth_basic $auth_type;
auth_basic_user_file /etc/nginx/.htpasswd;
}
Remember to:
- Regularly update the IP range list
- Monitor NGINX access logs for unexpected patterns
- Consider additional protections like rate limiting
- Test thoroughly before deploying to production
Always verify with:
sudo nginx -t
sudo systemctl reload nginx
Use curl to test from different IPs:
curl -I http://yourdomain.com
curl --user user:pass -I http://yourdomain.com