330 votes

Passage de chaînes codées en base64 dans une URL

Est-il sûr de transmettre des chaînes brutes codées en base64 via des paramètres GET ?

6 votes

Non, la question liée est plus récente. La question liée est donc un doublon de celle-ci...

2 votes

@serge Lequel ?

343voto

joeshmo Points 2439

Il existe des spécifications supplémentaires en base64. (Voir le tableau aquí pour les détails). Mais essentiellement, vous avez besoin de 65 caractères pour encoder : 26 minuscules + 26 majuscules + 10 chiffres = 62.

Vous avez besoin de deux autres ['+', '/'] et d'un caractère de remplissage '='. Mais aucun d'entre eux n'est compatible avec les url, donc utilisez simplement des caractères différents pour eux et vous êtes prêt. Les caractères standard du tableau ci-dessus sont ['-', '_'], mais vous pouvez utiliser d'autres caractères tant que vous les décodez de la même manière et que vous n'avez pas besoin de les partager avec d'autres.

Je vous recommande d'écrire vos propres aides. Comme celles-ci, issues des commentaires sur le site Page de manuel php pour base64_encode :

function base64_url_encode($input) {
 return strtr(base64_encode($input), '+/=', '._-');
}

function base64_url_decode($input) {
 return base64_decode(strtr($input, '._-', '+/='));
}

57 votes

Excellente solution, sauf que la virgule n'est pas sans réserve dans les URL. Je recommande d'utiliser '~' (tilde) ou '.' (point) à la place.

18 votes

@kralyk : je recommande d'utiliser simplement urlencode comme le suggère la réponse de rodrigo-silveira. Créer deux nouvelles fonctions pour gagner quelques caractères dans la longueur de l'url, c'est comme entrer dans votre maison en passant par la fenêtre au lieu d'utiliser la porte.

8 votes

@MarcoDemaio, sans savoir comment il sera utilisé, il est impossible de dire qu'il ne s'agit que de quelques caractères. Chaque caractère encodé aura une longueur triple, et pourquoi "+++..." ne serait-il pas une chaîne base64 valide ? Les URL ont des limites de navigateur, et tripler une URL pourrait vous faire atteindre ces limites.

267voto

Thiyagaraj Points 1364

Non, vous devrez le coder en url, car les chaînes de caractères en base64 peuvent contenir les caractères "+", "=" et "/" qui pourraient altérer la signification de vos données - ressemble à un sous-dossier.

Les caractères base64 valides sont les suivants.

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=

6 votes

Le codage des URL est un gaspillage d'espace, d'autant plus que la base64 elle-même laisse de nombreux caractères inutilisés.

35 votes

Je ne suis pas sûr de comprendre ce que vous dites - l'encodage des URL ne modifie aucun des caractères, à l'exception des trois derniers de la liste ci-dessus, et ce pour éviter qu'ils ne soient interprétés de manière incorrecte puisqu'ils ont d'autres significations dans les URL. Il en va de même pour la base64, les données d'origine peuvent être binaires ou autres, mais elles sont codées sous une forme qui peut être transmise facilement à l'aide de protocoles simples.

5 votes

Tout d'abord, vous devez également échapper le caractère '+' car il peut être converti en espace. Deuxièmement, il existe au moins quelques caractères qui peuvent être utilisés en toute sécurité dans les URL et qui ne sont pas utilisés dans le jeu de caractères "standard". Votre méthode peut même augmenter la taille des données transférées. trois fois dans certaines situations ; alors que le remplacement de ces caractères par d'autres fera l'affaire tout en conservant la même longueur. Et c'est aussi une solution assez standard.

97voto

rodrigo-silveira Points 2225

@joeshmo Ou au lieu d'écrire une fonction d'aide, vous pourriez simplement urlencoder la chaîne encodée en base64. Cela ferait exactement la même chose que votre fonction d'aide, mais sans la nécessité de deux fonctions supplémentaires.

$str = 'Some String';

$encoded = urlencode( base64_encode( $str ) );
$decoded = base64_decode( urldecode( $encoded ) );

3 votes

Le résultat n'est pas exactement le même. urlencode utilise 3 caractères pour coder les caractères non valides et la solution de joeshmo en utilise 1. Ce n'est pas une grande différence, mais c'est toujours un gaspillage.

1 votes

@JosefBorkovec Vraiment ? Alors cela signifierait également que le même nombre d'octets base64->url->encodés pourrait avoir une variété de longueurs différentes, alors que l'autre solution donne une longueur prévisible, non ?

1 votes

@humanityANDpeace Oui, urlencode est une solution de merde car elle triple la taille de certaines chaînes base64. Vous ne pouvez pas non plus réutiliser le tampon puisque la sortie est plus grande que l'entrée.

49voto

Note introductive J'ai envie d'apporter quelques clarifications, car certaines des réponses données ici étaient un peu trompeuses (voire incorrectes).

La réponse est NON vous ne pouvez pas simplement passer un paramètre codé en base64 dans une chaîne de requête URL, car les signes plus sont convertis en ESPACE dans le tableau global $_GET. En d'autres termes, si vous envoyez test.php?myVar=stringwith+sign à

//test.php
print $_GET['myVar'];

le résultat serait :
stringwith sign

La façon la plus simple de résoudre ce problème est de simplement urlencode() votre chaîne base64 avant de l'ajouter à la chaîne de requête pour échapper aux caractères +, = et / en codes %##. Par exemple, urlencode("stringwith+sign") renvoie à stringwith%2Bsign

Lorsque vous traitez l'action, PHP se charge de décoder automatiquement la chaîne de requête lorsqu'il remplit le global $_GET. Par exemple, si j'ai envoyé test.php?myVar=stringwith%2Bsign à

//test.php
print $_GET['myVar'];

le résultat serait :
stringwith+sign

Tu le fais. no veulent urldecode() la chaîne $_GET retournée, car les + seront convertis en espaces.
En d'autres termes, si j'ai envoyé le même test.php?myVar=stringwith%2Bsign à

//test.php
$string = urldecode($_GET['myVar']);
print $string;

le résultat est inattendu :
stringwith sign

Il serait prudent de rawurldecode() l'entrée, cependant, elle serait redondante et donc inutile.

1 votes

Belle réponse. Vous pouvez utiliser le code PHP sans les balises de début et de fin sur ce site si la question est balisée php (d'ailleurs, le plus souvent, c'est clair d'après le contexte de la question). Si vous ajoutez deux espaces à la fin d'une ligne, vous verrez apparaître le symbole <br> Il n'est donc pas nécessaire de taper beaucoup de HTML. J'espère que cela vous aidera, j'ai modifié un peu votre réponse pour l'améliorer encore plus.

1 votes

Merci de mentionner que PHP décode l'URL pour vous. Cela m'évite de tomber dans un terrier de lapin.

0 votes

Bonne réponse -> Vous ne voulez pas urldecode() la chaîne $_GET retournée car les + seront convertis en espaces. Cependant, vous pouvez sans risque utiliser la méthode rawurldecode() pour l'entrée,

19voto

Michał Górny Points 6450

Oui et non.

Le jeu de caractères de base64 peut dans certains cas entrer en conflit avec les conventions traditionnelles utilisées dans les URL. Mais de nombreuses implémentations de base64 vous permettent de modifier le jeu de caractères pour mieux correspondre aux URL ou même d'en fournir un (comme le jeu de caractères de Python). urlsafe_b64encode() ).

Un autre problème auquel vous pouvez être confronté est la limite de la longueur des URL ou plutôt l'absence d'une telle limite. Les normes ne spécifiant pas de longueur maximale, les navigateurs, serveurs, bibliothèques et autres logiciels utilisant le protocole HTTP peuvent définir leurs propres limites.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X