How to avoid encoding issues in urls with base64

This is part of the Semicolon&Sons Code Diary - consisting of lessons learned on the job. You're in the encoding category.

Last Updated: 2021-05-16

We had an unsubscribe link that was secured via a hashed uuid added to the URL. This hash, unfortunately, sometimes contained slashes, and whenever it did, the Laravel router got confused, thinking the user had requested a different resource altogether (instead of the unsubscribe one). I tried calling urlencode on the hash, but the problem persisted. Apparently the Laravel router also cannot handle URL encoded hashes.

So I decided to encode it with base64 instead. This character set should be perfect for channels that are only reliable with text content (e.g. for HTTP), right? So I thought. What you really want is base64_urlsafe instead.

Normal base64 uses the following characters:

Of course, 3 characters, + and / and =, are used in URLs. Therefore the urlsafe version of base64 needs some modifications:

Another solution, that works, is to take the normal base64 string, and then urlencode it using the standard tools, e.g. in Python / Ruby etc.