# Django IPware
**A Django application to retrieve client's IP address**
[![status-image]][status-link]
[![version-image]][version-link]
[![coverage-image]][coverage-link]
# Alternative package
If you prefer a python only version that does not integrate with Django directly, but allows for more flexibility and advanced features, you can use the [python-ipware](https://github.com/un33k/python-ipware) package instead. `django-ipware` is a wrapper using [python-ipware](https://github.com/un33k/python-ipware) under the hood staring from version `6.0.0`.
# Overview
**Best attempt** to get client's IP address while keeping it **DRY**.
# Notice
There is no perfect `out-of-the-box` solution against fake IP addresses, aka `IP Address Spoofing`.
You are encouraged to read the ([Advanced users](README.md#advanced-users)) section of this page and
use `trusted_proxies_ips` and/or `proxy_count` features to match your needs, especially `if` you are
planning to include `ipware` in any authentication, security or `anti-fraud` related architecture.
This is an open source project, with the source code visible to all. Therefore, it may be exploited through unimplemented, or improperly implemented features.
Please use ipware `ONLY` as a complement to your `firewall` security measures!
# How to install
1. easy_install django-ipware
2. pip install django-ipware
3. git clone http://github.com/un33k/django-ipware
a. cd django-ipware
b. run python setup.py install
4. wget https://github.com/un33k/django-ipware/zipball/master
a. unzip the downloaded file
b. cd into django-ipware-* directory
c. run python setup.py install
# How to use
```python
# In a view or a middleware where the `request` object is available
from ipware import get_client_ip
client_ip, is_routable = get_client_ip(request)
if client_ip is None:
# Unable to get the client's IP address
else:
# We got the client's IP address
if is_routable:
# The client's IP address is publicly routable on the Internet
else:
# The client's IP address is private
```
# Advanced users:
- ### Precedence Order
The default meta precedence order is top to bottom. You may customize the order
by providing your own `IPWARE_META_PRECEDENCE_ORDER` by adding it to your project's settings.py
```python
# The default meta precedence order (update as needed)
IPWARE_META_PRECEDENCE_ORDER = (
"X_FORWARDED_FOR", # Load balancers or proxies such as AWS ELB (default client is `left-most` [`<client>, <proxy1>, <proxy2>`])
"HTTP_X_FORWARDED_FOR", # Similar to X_FORWARDED_TO
"HTTP_CLIENT_IP", # Standard headers used by providers such as Amazon EC2, Heroku etc.
"HTTP_X_REAL_IP", # Standard headers used by providers such as Amazon EC2, Heroku etc.
"HTTP_X_FORWARDED", # Squid and others
"HTTP_X_CLUSTER_CLIENT_IP", # Rackspace LB and Riverbed Stingray
"HTTP_FORWARDED_FOR", # RFC 7239
"HTTP_FORWARDED", # RFC 7239
"HTTP_CF_CONNECTING_IP", # CloudFlare
"X-CLIENT-IP", # Microsoft Azure
"X-REAL-IP", # NGINX
"X-CLUSTER-CLIENT-IP", # Rackspace Cloud Load Balancers
"X_FORWARDED", # Squid
"FORWARDED_FOR", # RFC 7239
"CF-CONNECTING-IP", # CloudFlare
"TRUE-CLIENT-IP", # CloudFlare Enterprise,
"FASTLY-CLIENT-IP", # Firebase, Fastly
"FORWARDED", # RFC 7239
"CLIENT-IP", # Akamai and Cloudflare: True-Client-IP and Fastly: Fastly-Client-IP
"REMOTE_ADDR", # Default
)
```
**Alternatively**, you can provide your custom _request header meta precedence order_ when calling `get_client_ip()`.
```python
get_client_ip(request, request_header_order=['X_FORWARDED_FOR'])
get_client_ip(request, request_header_order=['X_FORWARDED_FOR', 'HTTP_X_FORWARDED_FOR'])
```
- ### Proxy Count
The default meta proxy count is 0 unless explictly provided as an argument to `get_client_ip()`. You may customize the order
by providing your own `IPWARE_META_PROXY_COUNT` by adding it to your project's settings.py
### Trusted Proxies
If your Django server is behind one or more known proxy server(s), you can filter out unwanted requests
by providing the `trusted` proxy list when calling `get_client_ip(request, proxy_trusted_ips=['177.139.233.133'])`.
In the following example, your load balancer (LB) can be seen as a `trusted` proxy.
```
`Real` Client <public> <---> <public> LB (Server) <private> <--------> <private> Django Server
^
|
`Fake` Client <private> <---> <private> LB (Server) <private> ---^
```
```python
# In the above scenario, use your load balancer IP address as a way to filter out unwanted requests.
client_ip, is_routable = get_client_ip(request, proxy_trusted_ips=['177.139.233.133'])
# If you have multiple proxies, simply add them to the list
client_ip, is_routable = get_client_ip(request, proxy_trusted_ips=['177.139.233.133', '177.139.233.134'])
# For proxy servers with fixed sub-domain and dynamic IP, use the following pattern.
client_ip, is_routable = get_client_ip(request, proxy_trusted_ips=['177.139.', '177.140'])
client_ip, is_routable = get_client_ip(request, proxy_trusted_ips=['177.139.233.', '177.139.240'])
```
`Please note:` By default, the `right-most` proxy in the chain is the `trusted` proxy and that is the one your django
server talks to. Therefore, `ipware` checks to see if the `right-most` proxy address starts with any ip pattern that was
passed in via the `proxy_trusted_ips` list.
### Proxy Count
If your Django server is behind a `known` number of proxy server(s), you can filter out unwanted requests
by providing the `number` of proxies when calling `get_client_ip(request, proxy_count=1)`.
In the following example, your load balancer (LB) can be seen as the `only` proxy.
```
`Real` Client <public> <---> <public> LB (Server) <private> <--------> <private> Django Server
^
|
`Fake` Client <private> ---^
```
```python
# In the above scenario, the total number of proxies can be used as a way to filter out unwanted requests.
client_ip, is_routable = get_client_ip(request, proxy_count=1)
# The above may be very useful in cases where your proxy server's IP address is assigned dynamically.
# However, If you have the proxy IP address, you can use it in combination to the proxy count.
client_ip, is_routable = get_client_ip(request, proxy_count=1, proxy_trusted_ips=['177.139.233.133'])
```
### Originating Request
If your proxy server is configured such that the right-most IP address is that of the originating client, you
can indicate `right-most` as your `proxy_order` when calling `get_client_ip(request, proxy_order="right-most")`.
Please note that the [de-facto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For) standard
for the originating client IP address is the `left-most` as per `<client>, <proxy1>, <proxy2>`.
# Running the tests
To run the tests against the current environment:
python manage.py test
# License
Released under a ([MIT](LICENSE)) license.
# Version
X.Y.Z Version
`MAJOR` version -- when you make incompatible API changes,
`MINOR` version -- when you add functionality in a backwards-compatible manner, and
`PATCH` version -- when you make backwards-compatible bug fixes.
[status-image]: https://github.com/un33k/django-ipware/actions/workflows/ci.yml/badge.svg
[status-link]: https://github.com/un33k/django-ipware/actions/workflows/ci.yml
[version-image]: https://img.shields.io/pypi/v/django-ipware.svg
[version-link]: https://pypi.python.org/pypi/django-ipware
[coverage-image]: https://coveralls.io/repos/un33k/django-ipware/badge.svg
[coverage-link]: https://coveralls.io/r/un33k/django-ipware
# Sponsors
[Neekware Inc.](http://neekware.com)
Raw data
{
"_id": null,
"home_page": "https://github.com/un33k/django-ipware",
"name": "django-ipware",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": null,
"author": "Val Neekman",
"author_email": "info@neekware.com",
"download_url": "https://files.pythonhosted.org/packages/23/64/c7e4791edf01ba483cce444770b3e6a930ba12195ba1eeb37b5bf6dce8a8/django-ipware-7.0.1.tar.gz",
"platform": null,
"description": "# Django IPware \n\n**A Django application to retrieve client's IP address**\n\n[![status-image]][status-link]\n[![version-image]][version-link]\n[![coverage-image]][coverage-link]\n\n# Alternative package\n\nIf you prefer a python only version that does not integrate with Django directly, but allows for more flexibility and advanced features, you can use the [python-ipware](https://github.com/un33k/python-ipware) package instead. `django-ipware` is a wrapper using [python-ipware](https://github.com/un33k/python-ipware) under the hood staring from version `6.0.0`.\n\n# Overview\n\n**Best attempt** to get client's IP address while keeping it **DRY**.\n\n# Notice\n\nThere is no perfect `out-of-the-box` solution against fake IP addresses, aka `IP Address Spoofing`.\nYou are encouraged to read the ([Advanced users](README.md#advanced-users)) section of this page and\nuse `trusted_proxies_ips` and/or `proxy_count` features to match your needs, especially `if` you are\nplanning to include `ipware` in any authentication, security or `anti-fraud` related architecture.\n\nThis is an open source project, with the source code visible to all. Therefore, it may be exploited through unimplemented, or improperly implemented features.\n\nPlease use ipware `ONLY` as a complement to your `firewall` security measures!\n\n# How to install\n\n 1. easy_install django-ipware\n 2. pip install django-ipware\n 3. git clone http://github.com/un33k/django-ipware\n a. cd django-ipware\n b. run python setup.py install\n 4. wget https://github.com/un33k/django-ipware/zipball/master\n a. unzip the downloaded file\n b. cd into django-ipware-* directory\n c. run python setup.py install\n\n# How to use\n\n```python\n # In a view or a middleware where the `request` object is available\n\n from ipware import get_client_ip\n client_ip, is_routable = get_client_ip(request)\n if client_ip is None:\n # Unable to get the client's IP address\n else:\n # We got the client's IP address\n if is_routable:\n # The client's IP address is publicly routable on the Internet\n else:\n # The client's IP address is private\n```\n\n# Advanced users:\n\n- ### Precedence Order\n\n The default meta precedence order is top to bottom. You may customize the order\n by providing your own `IPWARE_META_PRECEDENCE_ORDER` by adding it to your project's settings.py\n\n ```python\n # The default meta precedence order (update as needed)\n IPWARE_META_PRECEDENCE_ORDER = (\n \"X_FORWARDED_FOR\", # Load balancers or proxies such as AWS ELB (default client is `left-most` [`<client>, <proxy1>, <proxy2>`])\n \"HTTP_X_FORWARDED_FOR\", # Similar to X_FORWARDED_TO\n \"HTTP_CLIENT_IP\", # Standard headers used by providers such as Amazon EC2, Heroku etc.\n \"HTTP_X_REAL_IP\", # Standard headers used by providers such as Amazon EC2, Heroku etc.\n \"HTTP_X_FORWARDED\", # Squid and others\n \"HTTP_X_CLUSTER_CLIENT_IP\", # Rackspace LB and Riverbed Stingray\n \"HTTP_FORWARDED_FOR\", # RFC 7239\n \"HTTP_FORWARDED\", # RFC 7239\n \"HTTP_CF_CONNECTING_IP\", # CloudFlare\n \"X-CLIENT-IP\", # Microsoft Azure\n \"X-REAL-IP\", # NGINX\n \"X-CLUSTER-CLIENT-IP\", # Rackspace Cloud Load Balancers\n \"X_FORWARDED\", # Squid\n \"FORWARDED_FOR\", # RFC 7239\n \"CF-CONNECTING-IP\", # CloudFlare\n \"TRUE-CLIENT-IP\", # CloudFlare Enterprise,\n \"FASTLY-CLIENT-IP\", # Firebase, Fastly\n \"FORWARDED\", # RFC 7239\n \"CLIENT-IP\", # Akamai and Cloudflare: True-Client-IP and Fastly: Fastly-Client-IP\n \"REMOTE_ADDR\", # Default\n )\n ```\n\n **Alternatively**, you can provide your custom _request header meta precedence order_ when calling `get_client_ip()`.\n\n```python\nget_client_ip(request, request_header_order=['X_FORWARDED_FOR'])\nget_client_ip(request, request_header_order=['X_FORWARDED_FOR', 'HTTP_X_FORWARDED_FOR'])\n```\n\n- ### Proxy Count\n\n The default meta proxy count is 0 unless explictly provided as an argument to `get_client_ip()`. You may customize the order\n by providing your own `IPWARE_META_PROXY_COUNT` by adding it to your project's settings.py\n\n### Trusted Proxies\n\nIf your Django server is behind one or more known proxy server(s), you can filter out unwanted requests\nby providing the `trusted` proxy list when calling `get_client_ip(request, proxy_trusted_ips=['177.139.233.133'])`.\nIn the following example, your load balancer (LB) can be seen as a `trusted` proxy.\n\n```\n `Real` Client <public> <---> <public> LB (Server) <private> <--------> <private> Django Server\n ^\n |\n `Fake` Client <private> <---> <private> LB (Server) <private> ---^\n```\n\n```python\n# In the above scenario, use your load balancer IP address as a way to filter out unwanted requests.\nclient_ip, is_routable = get_client_ip(request, proxy_trusted_ips=['177.139.233.133'])\n\n# If you have multiple proxies, simply add them to the list\nclient_ip, is_routable = get_client_ip(request, proxy_trusted_ips=['177.139.233.133', '177.139.233.134'])\n\n# For proxy servers with fixed sub-domain and dynamic IP, use the following pattern.\nclient_ip, is_routable = get_client_ip(request, proxy_trusted_ips=['177.139.', '177.140'])\nclient_ip, is_routable = get_client_ip(request, proxy_trusted_ips=['177.139.233.', '177.139.240'])\n```\n\n`Please note:` By default, the `right-most` proxy in the chain is the `trusted` proxy and that is the one your django\nserver talks to. Therefore, `ipware` checks to see if the `right-most` proxy address starts with any ip pattern that was\npassed in via the `proxy_trusted_ips` list.\n\n### Proxy Count\n\nIf your Django server is behind a `known` number of proxy server(s), you can filter out unwanted requests\nby providing the `number` of proxies when calling `get_client_ip(request, proxy_count=1)`.\nIn the following example, your load balancer (LB) can be seen as the `only` proxy.\n\n```\n `Real` Client <public> <---> <public> LB (Server) <private> <--------> <private> Django Server\n ^\n |\n `Fake` Client <private> ---^\n```\n\n```python\n# In the above scenario, the total number of proxies can be used as a way to filter out unwanted requests.\nclient_ip, is_routable = get_client_ip(request, proxy_count=1)\n\n# The above may be very useful in cases where your proxy server's IP address is assigned dynamically.\n# However, If you have the proxy IP address, you can use it in combination to the proxy count.\nclient_ip, is_routable = get_client_ip(request, proxy_count=1, proxy_trusted_ips=['177.139.233.133'])\n```\n\n### Originating Request\n\nIf your proxy server is configured such that the right-most IP address is that of the originating client, you\ncan indicate `right-most` as your `proxy_order` when calling `get_client_ip(request, proxy_order=\"right-most\")`.\nPlease note that the [de-facto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For) standard\nfor the originating client IP address is the `left-most` as per `<client>, <proxy1>, <proxy2>`.\n\n# Running the tests\n\nTo run the tests against the current environment:\n\n python manage.py test\n\n# License\n\nReleased under a ([MIT](LICENSE)) license.\n\n# Version\n\nX.Y.Z Version\n\n `MAJOR` version -- when you make incompatible API changes,\n `MINOR` version -- when you add functionality in a backwards-compatible manner, and\n `PATCH` version -- when you make backwards-compatible bug fixes.\n\n[status-image]: https://github.com/un33k/django-ipware/actions/workflows/ci.yml/badge.svg\n[status-link]: https://github.com/un33k/django-ipware/actions/workflows/ci.yml\n[version-image]: https://img.shields.io/pypi/v/django-ipware.svg\n[version-link]: https://pypi.python.org/pypi/django-ipware\n[coverage-image]: https://coveralls.io/repos/un33k/django-ipware/badge.svg\n[coverage-link]: https://coveralls.io/r/un33k/django-ipware\n\n# Sponsors\n\n[Neekware Inc.](http://neekware.com)\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A Django application to retrieve user's IP address",
"version": "7.0.1",
"project_urls": {
"Homepage": "https://github.com/un33k/django-ipware"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "1133bf539925b102d68200da5b1d3eacb8aa5d5d9a065972e8b8724d0d53bb0d",
"md5": "484b30de32a2dfc4a1291a6a78cd5eb6",
"sha256": "db16bbee920f661ae7f678e4270460c85850f03c6761a4eaeb489bdc91f64709"
},
"downloads": -1,
"filename": "django_ipware-7.0.1-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "484b30de32a2dfc4a1291a6a78cd5eb6",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": ">=3.8",
"size": 6425,
"upload_time": "2024-04-19T20:02:47",
"upload_time_iso_8601": "2024-04-19T20:02:47.469918Z",
"url": "https://files.pythonhosted.org/packages/11/33/bf539925b102d68200da5b1d3eacb8aa5d5d9a065972e8b8724d0d53bb0d/django_ipware-7.0.1-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "2364c7e4791edf01ba483cce444770b3e6a930ba12195ba1eeb37b5bf6dce8a8",
"md5": "9e38cf13dbcac291bee8886d27f63651",
"sha256": "d9ec43d2bf7cdf216fed8d494a084deb5761a54860a53b2e74346a4f384cff47"
},
"downloads": -1,
"filename": "django-ipware-7.0.1.tar.gz",
"has_sig": false,
"md5_digest": "9e38cf13dbcac291bee8886d27f63651",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 6827,
"upload_time": "2024-04-19T20:02:49",
"upload_time_iso_8601": "2024-04-19T20:02:49.257861Z",
"url": "https://files.pythonhosted.org/packages/23/64/c7e4791edf01ba483cce444770b3e6a930ba12195ba1eeb37b5bf6dce8a8/django-ipware-7.0.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-04-19 20:02:49",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "un33k",
"github_project": "django-ipware",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "django-ipware"
}