diff --git a/CHANGELOG.md b/CHANGELOG.md index 32bb2dc..8f2f4f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,12 +4,21 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## 3.0.0 - 2023-09-30 -### Fixed +### Changed + +- Use faster SHA512-based key hasher instead of password hashers. Reduces server load by making API key validation orders of magnitude faster (10x to 30x according to estimations, network latency aside). Hashed key will be transparently upgraded the first time `.is_valid()` is called. (Pull #244, Pull #251) + +### Removed +- Dropped support for Python 3.7, which has reached EOL. (Pull #247) - Drop redundant `.has_object_permission()` implementation on `BaseHasAPIKey` when using DRF 3.14.0 or above. (Pull #240) +### Added + +- Add official support for Python 3.11. (Pull #247) + ## 2.3.0 - 2023-01-19 ### Removed diff --git a/README.md b/README.md index df16f9b..8fea5a8 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ They can also present enough security for authorizing internal services, such as Install with `pip`: ```bash -pip install "djangorestframework-api-key==2.*" +pip install "djangorestframework-api-key==3.*" ``` _**Note**: It is highly recommended to **pin your dependency** to the latest major version (as depicted above), as breaking changes may and will happen between major releases._ diff --git a/docs/guide.md b/docs/guide.md index 353dbd6..756d50f 100644 --- a/docs/guide.md +++ b/docs/guide.md @@ -7,7 +7,7 @@ Install with `pip`: ```bash -pip install "djangorestframework-api-key==2.*" +pip install "djangorestframework-api-key==3.*" ``` _**Note**: It is highly recommended to **pin your dependency** to the latest major version (as depicted above), as breaking changes may and will happen between major releases._ diff --git a/docs/index.md b/docs/index.md index d675d3e..9a1f529 100644 --- a/docs/index.md +++ b/docs/index.md @@ -58,7 +58,7 @@ They can also present enough security for authorizing internal services, such as Install with `pip`: ```bash -pip install "djangorestframework-api-key==2.*" +pip install "djangorestframework-api-key==3.*" ``` !!! important diff --git a/docs/upgrade/3.0.md b/docs/upgrade/3.0.md new file mode 100644 index 0000000..b8b71d8 --- /dev/null +++ b/docs/upgrade/3.0.md @@ -0,0 +1,35 @@ +# Upgrading to 3.0 + +## Introduction + +This document lists the steps necessary to upgrade from 2.x to 3.0. + +The full list of changes can be found in the [Changelog](https://github.com/florimondmanca/djangorestframework-api-key/blob/master/CHANGELOG.md). + +## Steps + +### 1. Upgrade your Python to 3.8+ + +The 3.0 release drops support for Python 3.7, which has reached EOL in June 2023. + +Before upgrading, make sure you are running on Python 3.8 or above. + +### 2. Review usage of `.has_object_permission()` on DRF 3.14+ with custom API key models + +An implementation of `.has_object_permission()` on `BaseHasAPIKey` that was redundant with `.has_permission()` has been dropped when using Django REST Framework 3.14.0 and above. + +If you are using DRF 3.14+ and have custom API key models, you will want to review any implementation of `.has_object_permission()`. Calls to `super().has_object_permission()` will now return `True` (the DRF default) instead of re-validating the API key. This is the desirable thing to do, but you may need some adjustements if you relied on the previous behavior somehow until now. + +### 3. Review upgrade of API key hashes following switch to SHA512 + +This release brings a notable performance improvement by changing the hashing algorithm for API keys. + +Hashing API keys used to be done using Django's `PASSWORD_HASHERS`. These hashers are slow by design as they're meant to deal with low-entropy strings such as user passwords. As a result, they typically added 200ms or more on every single request. On the contrary, API keys are long, randomly generated strings of ASCII characters. This means they have a high entropy, so we can get away with hashing them with a simpler — and faster — algorithm. + +Consequently, version 3.0 now uses SHA512 for hashing API keys. + +Limited testing has shown API key verification should be at least 10x faster on typical CPUs — although greater improvements could be observed. + +The hashes of existing API keys will be transparently updated the next time `.is_valid()` is called (i.e. the next time the API key is used). + +There shouldn't be any action required on your side, but you may want to test things in a staging environment out of caution. diff --git a/mkdocs.yml b/mkdocs.yml index ee1e5be..a49951f 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -15,6 +15,7 @@ nav: - User Guide: guide.md - Security: security.md - Upgrade Guides: + - "3.0": upgrade/3.0.md - "2.0": upgrade/2.0.md - "1.4": upgrade/1.4.md - "1.0": upgrade/1.0.md diff --git a/src/rest_framework_api_key/__init__.py b/src/rest_framework_api_key/__init__.py index 732566a..d102040 100644 --- a/src/rest_framework_api_key/__init__.py +++ b/src/rest_framework_api_key/__init__.py @@ -6,6 +6,6 @@ if django.VERSION < (3, 2): # pragma: no cover default_app_config = "rest_framework_api_key.apps.RestFrameworkApiKeyConfig" -__version__ = "2.3.0" +__version__ = "3.0.0" __all__ = ["__version__", "default_app_config"]