Closed nbolender closed 6 months ago
The error looks like a 401 (Unauthorised), which is thrown when the request signature passed as a query param ik-s
is invalid.
@nbolender Is this happening with any other URLs on the same account identifier i.e. patchboard/echl
? Probably one without a diacritic (“é”).
@harshit-budhraja This does not occur on URLs without a diacritic (using the same SDK and same credentials). I believe it is an error in generating the signature, either in this SDK or on the server.
@nbolender As per the documentation:
Signing the URLs adds additional query parameters to ensure that image transformations cannot be altered from the URL. If someone tries to modify the image transformation or the image URL or use it beyond its intended expiry time, a 401 Unauthorised response status code is returned.
For the image in question, can we confirm the following:
The signature is created using the SDK and not via your own code? If latter is the case, we'd want to make sure that the signing logic is correct. Ref: https://docs.imagekit.io/features/security/signed-urls#pseudo-code-for-signed-url-generation
Is the URL you're trying to access exactly same (including the transformation params) as the the one used to generate the signature? In this case, the path which should ideally be signed is: echl/production/tr/post/679/featured_image/7a32dac7-94d3-4617-b093-bb9c403c1e68/Pascal-Rhéaume-1920-1080.jpeg
and the transformation parameters as required.
The expiry is set correctly? Trying to access an expired image also gives 401.
@nbolender I've tried reproducing the mentioned issue but it seems that it's working perfectly fine for me with diacritics.
Versions:
"name": "imagekit/imagekit",
"version": "3.0.3",
➜ php-test composer -V
Composer version 2.6.5 2023-10-06 10:11:52
➜ php-test php -v
PHP 8.2.12 (cli) (built: Oct 24 2023 19:22:16) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.2.12, Copyright (c) Zend Technologies
with Zend OPcache v8.2.12, Copyright (c), by Zend Technologies
Here's my sample code:
<?php
// SDK initialization
// Require the Composer autoloader.
require 'vendor/autoload.php';
use ImageKit\ImageKit;
$imageKit = new ImageKit(
"public key",
"private key",
"url"
);
$imageURL = $imageKit->url([
"path" => "/four-penguins-with-é.png",
"queryParameters" =>
[
"v" => "123"
],
"transformation" => [
[
"e-shadow" => "st-50_bl-15"
]
],
"signed" => true,
"expireSeconds" => 86400,
]);
echo $imageURL;
?>
And the generated signed url works for me: https://ik.imagekit.io/oq1pyotaq/tr:e-shadow-st-50_bl-15/four-penguins-with-é.png?v=123&ik-t=1699616879&ik-s=0ea0d21e4a874e519a4a2f416e540561fe978866%25
@harshit-budhraja try changing signature in your URL, if it still works that means correctness of signature is not being tested. You would need to ensure Allow only signed URL setting is turned on for signature check to matter.
@harshit-budhraja Yes, I am using this PHP SDK v3.0.3. I'm not using expire dates, but using it does not fix the issue.
Note that an important difference between my example and yours is that you are using your account's default URL endpoint, and I am using a custom one.
php > $imagekit = new \ImageKit\ImageKit($public, $private, 'https://ik.imagekit.io/patchboard/echl');
php > echo $imagekit->url(['path' => '/four-penguins-with-e.png', 'signed' => true]);
https://ik.imagekit.io/patchboard/echl/four-penguins-with-e.png?ik-s=1754cb577de25067b61728d415ce74be56e054f3
# Works
php > echo $imagekit->url(['path' => '/four-penguins-with-é.png', 'signed' => true]);
https://ik.imagekit.io/patchboard/echl/four-penguins-with-é.png?ik-s=b670c33b4d9fcfe6e1ef198b7df6ed4ae85c9e47
# Doesn't work
php > echo $imagekit->url(['path' => '/four-penguins-with-e.png', 'signed' => true, 'expireSeconds' => 604800]);
https://ik.imagekit.io/patchboard/echl/four-penguins-with-e.png?ik-t=1700154382&ik-s=f598511ccc5008d0645de4c1daaa63226c5b1c5c
# Works
php > echo $imagekit->url(['path' => '/four-penguins-with-é.png', 'signed' => true, 'expireSeconds' => 604800]);
https://ik.imagekit.io/patchboard/echl/four-penguins-with-é.png?ik-t=1700154389&ik-s=325533548b97efbba592549d2b2af01f8ef32f53
# Doesn't work
Adding a transformation doesn't change anything:
php > echo $imagekit->url(['path' => '/four-penguins-with-e.png', 'signed' => true, 'transformation' => [['e-shadow' => 'st-50_bl-15']]]);
https://ik.imagekit.io/patchboard/echl/tr:e-shadow-st-50_bl-15/four-penguins-with-e.png?ik-s=fb3010cd3b120d6990f271968ea10460ad502818
# Works
php > echo $imagekit->url(['path' => '/four-penguins-with-é.png', 'signed' => true, 'transformation' => [['e-shadow' => 'st-50_bl-15']]]);
https://ik.imagekit.io/patchboard/echl/tr:e-shadow-st-50_bl-15/four-penguins-with-é.png?ik-s=d6731d835653345c6c1d578d9ec39b9bb449c107
# Doesn't work
I even tried moving the URL endpoint to the path, but that does not work for any image:
php > $imagekit = new \ImageKit\ImageKit($public, $private, 'https://ik.imagekit.io');
php > echo $imagekit->url(['path' => '/patchboard/echl/four-penguins-with-e.png', 'signed' => true]);
https://ik.imagekit.io/patchboard/echl/four-penguins-with-e.png?ik-s=00c996b5dc353ca2fd27941acb54d749db768a2b
# Doesn't work
php > echo $imagekit->url(['path' => '/patchboard/echl/four-penguins-with-é.png', 'signed' => true]);
https://ik.imagekit.io/patchboard/echl/four-penguins-with-é.png?ik-s=ca11d66a0a3710e7743b44b7af70c22f5a972eb8
# Doesn't work
php > $imagekit = new \ImageKit\ImageKit($public, $private, 'https://ik.imagekit.io/patchboard');
php > echo $imagekit->url(['path' => '/echl/four-penguins-with-e.png', 'signed' => true]);
https://ik.imagekit.io/patchboard/echl/four-penguins-with-e.png?ik-s=a5531aa7948c4de65c995b7c220d5b639102e2ce
# Doesn't work
php > echo $imagekit->url(['path' => '/echl/four-penguins-with-é.png', 'signed' => true]);
https://ik.imagekit.io/patchboard/echl/four-penguins-with-é.png?ik-s=aa20b72737683f7466d1c642f0cea8d983a44053
# Doesn't work
And to be clear I am using an S3 origin.
I tried uploading the files to the ImageKit media library to test, but even the upload fails in the dashboard when uploading a file with a diacritic.
@nbolender We've successfully investigated this. Here're the findings:
Most browser engines encode special characters, diacritics or characters from different charsets to UTF-8. For example, é
(diacritic) is encoded as e%CC%81
, and so on. What this means is - that while encoding /four-penguins-with-é.png
, the signing happens on the URL with the diacritic é
, but while accessing the URL via a browser or via a mobile platform SDK, the URL being accessed is the UTF-8 encoded one. Hence, to fix this - Use a UTF-8 encoded URL at the time of signing.
For more details: https://docs.imagekit.io/features/security/signed-urls#signed-urls-with-special-characters-and-diacritics
@harshit-budhraja Well, what you are doing is not encoding the URL in UTF-8, but instead taking a UTF-8 string and making it ASCII. I would argue that this is the responsibility of the SDK if it is a requirement.
The example given also does not work, because it will encode the forward slash as %2F and fail. To get it to work, I have to do something like this:
$path = '/penguin/four-penguins-with-é.png';
$parts = explode('/', $path);
$new_path = '';
foreach ($parts as $part) {
if (!empty($part)) {
$new_path .= '/' . urlencode($part);
}
}
That's a lot of work, considering I had a properly-encoded UTF-8 string to start with, that works when accessing the source image directly from S3.
@nbolender it makes sense to handle this in SDK. We will review it again and keep this issue open for now. Thank you so much for providing this information.
@nbolender this is fixed in version 4.0.1. PR - https://github.com/imagekit-developer/imagekit-php/pull/65
I am having an issue with signed URLs. When the URL contains a diacritic (“é”), I get an error indicating an invalid request signature. I am not sure if the issue lies with the PHP SDK or with the server.
An example URL that is failing is: https://ik.imagekit.io/patchboard/echl/tr:c-at_max,fo-auto,ar-16-9,w-1000/production/tr/post/679/featured_image/7a32dac7-94d3-4617-b093-bb9c403c1e68/Pascal-Rhéaume-1920-1080.jpeg?ik-s=ea10ab0f3dd47f19921f9851576805edcaadfb71