This guide walks you through a simple and secure setup to capture screenshots through nginx. This guide is particularly useful if you want to:
img
tags
Add this location
block to your nginx configuration
(don't forget to replace your access key).
1 2 3 4 | location /screenshot {
set $args $args&access_key=YOUR_ACCESS_KEY_HERE
proxy_pass https://api.apiflash.com/v1/urltoimage;
}
|
This block is proxying each /screenshot
request to ApiFlash's screenshot API endpoint.
Using the set
directive, your access key is directly added by nginx to the query string
parameters. As a result your end users cannot get your access key. Screenshots are served from
your own domain and you can directly include screenshot URLs into img
tags.
1 | <img src="https://yourdomain.com/screenshot?url=https://ok.com"/>
|
Even though this setup is useful already, an end user could use your /screenshot
endpoint to capture arbitrary screenshots.
Another layer of security can be added with an if
block to restrict the allowed target
URLs.
1 2 3 4 5 6 7 8 9 | location /screenshot {
if ( $arg_url !~* https:\/\/somedomain.com ){
return 403;
}
set $args $args&access_key=YOUR_ACCESS_KEY_HERE
proxy_pass https://api.apiflash.com/v1/urltoimage;
}
|
This if
block ensures nginx returns an HTTP 403 Forbidden
error when
URLs don't match the specified regular expression. In particular, in the previous example, only URLs
that begin with https://somedomain.com
can be captured as screenshots.
End users cannot capture arbitrary screenshots with this setup. But they can still make a lot of
HTTP
requests to your /screenshot
endpoint and potentially consume your subscription quota
as a result.
Rate limiting your endpoint is a good way to ensure that end users cannot aggressively call the
/screenshot
endpoint. Depending on your use case and the volume you're expecting, you
might want to adjust the rate limit and the burst size.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | limit_req_zone $binary_remote_addr zone=rate_limit:50m rate=1r/s;
server {
# The rest of your server configuration...
location /screenshot {
limit_req zone=rate_limit burst=10;
if ( $arg_url !~* https:\/\/google.com ){
return 403;
}
set $args $args&access_key=YOUR_ACCESS_KEY_HERE;
proxy_pass https://api.apiflash.com/v1/urltoimage;
}
}
|
In the previous example, requests are rate limited based on IP address and are limited to 1 request per second. With a burst size of 10, up to 10 requests can be queued per IP address without being dropped by nginx.
On public pages with high traffic, if you use the /screenshot
endpoint directly in
img
tags, this will result in a lot of unnecessary requests to ApiFlash. To ensure that
ApiFlash's rate limit is not exceeded, you need to configure nginx to cache the generated
screenshots.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | proxy_cache_path /screenshot_cache levels=1:2 keys_zone=screenshot_cache:10m
max_size=2g inactive=86400s use_temp_path=off;
limit_req_zone $binary_remote_addr zone=rate_limit:50m rate=1r/s;
server {
# The rest of your server configuration...
location /screenshot {
limit_req zone=rate_limit burst=10;
if ( $arg_url !~* https:\/\/google.com ){
return 403;
}
set $args $args&access_key=YOUR_ACCESS_KEY_HERE;
proxy_pass https://api.apiflash.com/v1/urltoimage;
proxy_cache screenshot_cache;
proxy_cache_lock on;
proxy_cache_key $request_uri$request_body;
proxy_cache_bypass $arg_fresh;
proxy_ignore_headers Vary Set-Cookie;
}
}
|
The previous configuration is caching up to 2GB of screenshots for 24 hours in the
/screenshot_cache
directory. Various nginx proxy directives are used to fine tune the
caching behavior. More information about those directives can be found in the
nginx documentation
.