π IP and Geo Rules
When to use thisβ
Licensing restrictionsβ
Sometimes, you might have to restrict or whitelist countries to watch your videos on your app to meet with specific licensing requirements.
Security reasonsβ
You might wish to block specific set of IPs which you know to be malicious actors. Or if your service is not available in a region, you can block access.
Restricting OTP to specific IP (Recommended)β
When you are generating OTP on your backend, you also get value of the IP address of the user watching the video. It is strongly recommended to restrict the OTP to this particular IP address along with other rules. You will find sample configuration for using this below.
Specificationβ
The POST request to generate a new OTP take a JSON body with several keys. This one requires setting new key called ipGeo
This parameter will take an object with either an allow
list or a block
list.
Both of these are going to be an array of strings. An except
list will contain
exceptions to the allow
or block
lists when needed.
name | type | description |
---|---|---|
allow | string[] | list of country codes and IP addresses to allow |
block | string[] | list of country codes and IP addresses to block |
except | string[] | exception to the allow or the block list above |
The country list will accept a list of two-letter country codes. The acceptable list of countries is the ISO 3166-1 alpha2
The IP addresses can only be ipv4 addresses in the most common dotted-decimal notation. e.g. 123.123.123.123
ipv6 supportβ
ipv6 is the new IP address space created to fix the problem of scarcity of ipv4 address. Since ipv6 is not available at most websites, ISPs provide either ipv4-only or ipv4+ipv6 connectivity.
Similarly, when setting up your servers on a cloud such as AWS or Google Cloud, you get an option to either make it ipv4-only (which is the default) or make it dual-stack (with both ipv4 and ipv6) connectivity.
ipv6 address is received at your servers only when the server is configured for ipv6 dualstack and the user has received an ipv6 address from their ISP.
Currently, this API only supports ipv4 address. If you are getting ipv6 address from your user, you should not pass it to this API.
How to get your user's IP addressβ
All programming languages have some provision of getting IP address of the connecting client. This only works when your web server process is directly listening on the internet. In most situations, you will have some middleware between your web server and the client.
The X-Forwarded-For
header is used for identifying the originating IP address of
a client connecting to a web server through an HTTP proxy or a load balancer.
When traffic is intercepted between clients and servers, the IP received at
process is the internal IP address of the proxy or load balancer only. To see
the original IP address of the client, the X-Forwarded-For request header is
used.
Middlewares can exist both at the client-side (proxy servers) and server-side (reverse proxy, load balancer, etc.). Both will append their received addresses on the forwarded-for header. What you need is the public-facing IP address of the client. To do this, you need to know the number of server-side middlewares.
As an example, let's say you have two middlewares: an nginx reverse proxy and a load balancer. You received the following as IP and forwarded_for:
ip: 10.2.3.4
x-forwarded-for: 192.168.0.1, 123.123.123.123, 172.0.1.2
Here, the IP received (10.2.3.4) is that of the reverse proxy, the first forwarded_for (192.168.0.1) is the IP of load-balancer. The next IP (123.123.123.123) is the public-facing IP of the client that you need for this API. There can be more IPs after that one in the forwarded_for to denote the network proxy configuration at the client's end.
If you have a CDN also, there will be one extra IP for that too. In that case, you must also ensure that caching is disabled at the CDN layer for all authenticated requests.
Associated Error conditionsβ
When generating OTPβ
If you receive a 400 status code when using this parameter to generate OTP, read the HTTP response during this error. The response will contain a JSON which will tell you exactly why the input caused the error. Possible errors:
- only one of allow or block allowed
- one of allow or block required
- Input list should be a string array
- Empty array received
- Except should be an array
When playing a restricted videoβ
Code: 2014
Message: Not allowed in your region or network
Sample configurationsβ
Most of your use-case will fall among one of the below listed requirements. You can modify the samples below to suit your specifications. If you need help making any custom rule or you just like us to verify the rule, feel free to email our support at support@vdocipher.com
allow only specific IPβ
{allow: [ip1]}
block set of countriesβ
{block: [c1, c2, c3]}
allow only a set of countriesβ
{allow: [c1, c2, c3]}
block specific IPβ
{block: [ip1]}
allow one country and one IP wherever it isβ
{allow: [ip1, c1]}
block set of countries except one IPβ
{block: [c1, c2], except: [ip1]}
allow specific IP when it is among set of countriesβ
{allow: [ [ip1, c1, c2, c3] ]}
allow specific IP unless it is among set of countriesβ
{allow: [ip1], except: [c1, c2, c3]}
Allow set of countries and block set of IPs wherever they are fromβ
{allow: [c1, c2, c3], except: [ip1, ip2, ip3]}
Get OTP Sample Codeβ
- CURL
- NODE
- PHP
- C#
- Python
- Ruby
curl -X POST \
https://dev.vdocipher.com/api/videos/1234567890/otp \
-H 'Accept: application/json' \
-H 'Authorization: Apisecret a1b2c3d4e5' \
-H 'Content-Type: application/json' \
-d '{
"ipGeo": {"allow": ["312.312.312.312"]}
}'
var request = require('request');
var options = {
method: 'POST',
url: 'https://dev.vdocipher.com/api/videos/1234567890/otp',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Apisecret a1b2c3d4e5',
},
body: {
ipGeo: {allow: ['312.312.312.312']},
},
json: true,
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://dev.vdocipher.com/api/videos/1234567890/otp",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'ipGeo' => ['allow' => ['312.312.312.312']]
]),
CURLOPT_HTTPHEADER => array(
"Accept: application/json",
"Authorization: Apisecret a1b2c3d4e5",
"Content-Type: application/json"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
var client = new RestClient("https://dev.vdocipher.com/api/videos/1234567890/otp");
var request = new RestRequest(Method.POST);
request.AddHeader("Accept", "application/json");
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Authorization", "Apisecret a1b2c3d4e5");
request.AddParameter("undefined", "{\n\t\"ipGeo\": {\"allow\": [\"312.312.312.312\"]}\n}",
ParameterType.
RequestBody);
IRestResponse response = client.Execute(request);
import requests
import json
url = "https://dev.vdocipher.com/api/videos/1234567890/otp"
payload = json.dumps({
"ipGeo": {'allow': ['312.312.312.312']}
})
headers = {
'Authorization': "Apisecret a1b2c3d4e5",
'Content-Type': "application/json",
'Accept': "application/json"
}
response = requests.request("POST", url, data=payload, headers=headers)
print(response.text)
require 'uri'
require 'json'
require 'net/http'
url = URI("https://dev.vdocipher.com/api/videos/1234567890/otp")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Apisecret a1b2c3d4e5'
request["Content-Type"] = 'application/json'
request["Accept"] = 'application/json'
request.body = {
:ipGeo => {'allow': ['312.312.312.312']}
}.to_json
response = http.request(request)
puts response.read_body
The code samples above uses a fake IP 312.312.312.312
. That needs to be
replaced to make it work.