Deal with `private-user-images` when Fetching GitHub Discussion Body
Published in
Blog/en
on12/9/2023
.
When I built the new version of this blog, I used the bodyHTML that was provided by the GitHub Discussions API to improve performance. Everything went well at first, but when I set a cache for the content, the images were all broken. I found private-user-images.githubusercontent.com maybe caused this problem. This blog will introduce how I dealt with it.
Broken Images
I set a cache for the API to improve the performance and avoid extra requests. At first, I set the max-age
to 60 * 60
which means an hour. However, about 5 more minutes later, all the images in the article were broken. When I opened the developer panel in my browser, I found that the source URLs of these images were not the original URL.
In the editor of the discussion body, my image URL was:
![](https://github.com/ocoke/Biscus/assets/71591824/b6b47ca0-f77c-432a-8c0f-942a9b204b0a)
However, when it was rendered to HTML by the API, it turned into:
<img src="https://private-user-images.githubusercontent.com/71591824/286707243-b6b47ca0-f77c-432a-8c0f-942a9b204b0a.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTEiLCJleHAiOjE3MDIwOTQ0MjMsIm5iZiI6MTcwMjA5NDEyMywicGF0aCI6Ii83MTU5MTgyNC8yODY3MDcyNDMtYjZiNDdjYTAtZjc3Yy00MzJhLThjMGYtOTQyYTliMjA0YjBhLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFJV05KWUFYNENTVkVINTNBJTJGMjAyMzEyMDklMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjMxMjA5VDAzNTUyM1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWI5ZGQ3ZTNhN2VkZGI1ZTM0MDljMTM2MDAwMTMzZDY1YjdiMTdmYjBiYmZiOTQxYzEyMTlhNWQxY2U5OWJjYzcmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.xw9990CeWP9d-lOCY_Be1co9hATFX-XYjXZCx2CnQF0" alt="" style="max-width: 100%;">
The URL became super long with a token in it, and the source domain became private-user-images.githubusercontent.com
. I found the token was in JWT
format (and also the query key mentioned that).
Decode JWT
Okay, let's figure out this from the ?jwt=
.
Open https://jwt.io/ , and paste the full token into the Encoded
.
Then, we can find there are several useful pieces of information in the payload
.
For example, the exp
is for the expiration time, and the nbf
is for the not valid before
.
So we can infer that the expiration time for the image is 5 minutes. Because we set an hour cache at first, after the first 5 minutes, the images will be unavailable.
Solution
We can set the cache to 5 minutes to avoid the expiration happening. It will work and this is the easiest way to solve this issue.
We can also fetch body
with the API to return the raw markdown format body. Then, we'll need to match and get all the source images' URLs to replace them (although this is not a good idea).
Or we can render the markdown content by ourselves or call /markdown
API on api.github.com
.