Things are harder than I thought! It turns out that this thing I'm building is quite complex. And GitHub isn't making it easier.
- Authenticating as a GitHub App
To do this, you need to create a private key for your app through the app's settings. Then, you use that key to generate a JWT, which lasts for up to 10 minutes. You can use this JWT to access high-level info about your app (e.g. how many times it's been installed). Not particularly useful for my use case.
- Authenticating as an installation
An installation is either done on a personal account or an organization. You can choose which repositories the installation can access (all vs. a subset). Authenticating as an installation works by creating an access token using the JWT created above. When creating an access token, you can select a subset of the repositories available to the app. With the access token, you can do whatever you specified on the permissions list. It expires within an hour.
- Authenticating on behalf of a user (with OAuth)
This is your regular OAuth authentication. Users are redirected to authenticate on GitHub, where they can accept/reject your application. Once accepted, you'll have an access token that you can use to perform actions on behalf of that user.
For my app, I need two things:
- The app should be able to perform actions on behalf of the user if they're authenticated.
- The app should be able to serve non-personalized content to unauthenticated users.
The first one is not a problem as I just need to use the OAuth scheme. The second one, however, is a bit tricky.
See, I need to use GitHub's GraphQL API (at least for the time being). Unlike the REST API, the GraphQL API doesn't allow anonymous access. That is, you need to authenticate before using it. Even if you only want to read a publicly available resource.
If you're using a Personal Access Token (PAT), it's straightforward. You just
need to include it in the
Authorization header, and it's done. However, I
don't want the app to be tied to my PAT. I don't want to create a separate
account just for this either.
I only need to query a publicly available resource. Thus, I only need an access token that's accepted by the GraphQL API. That token does not need any permissions.
Using just the JWT doesn't work. I had to create an access token by authenticating as an installation. Which installation it is, and which repositories can be accessed, are not important. I literally just need a valid access token. Thus, I did the absolute minimum: I select an arbitrary installation of the app (e.g. my account) and not select any repository for the token. It works!
Still... I kinda wish it were simpler. If GitHub had allowed anonymous access to their GraphQL API, I would've only needed to worry about the OAuth scheme.
There's also another annoying thing: the API that I want to use is still fairly
new. To enable it, a
GraphQL-Features header should be set. The problem is,
when sending a preflight request, the server doesn't include
Access-Control-Allow-Headers response header.
This effectively means that the API is unusable from a web browser. Therefore, I need to create a service that forwards the requests to GitHub. Arrgh.
Anyway, all of this is so far only for the basic read functionality of the app. Things will surely get more complex from here. I'd have to dig more on GraphQL as well (it's my first time using it).
I can't wait to make it public!
Work is getting harder. I'm quite surprised. The previous weeks, I was only working on a few pages with a read-only table.
Now, I'm handling a form with several Autocomplete fields (one of them creatable), with an arbitrary number of a field group (it can be added/removed). Some of the fields also happen to be connected with a global Redux state. I'm still pretty new to front-end stuff, so this is quite overwhelming.
I rode my bike on Friday! It was fun, but I kind of exhausted myself. I guess I shouldn't have gone too far.
I watched some episodes of The Twilight Zone (the original one, with Rod Serling) again. I had been watching it a few months ago and got into the third season. University stuff came along and I couldn't find the time to watch the show, so I left it there. It's interesting to see how many things in the show are still relevant to this day.
I also rewatched some episodes of Better Call Saul. My sister continued her binge-watch after finishing Breaking Bad and El Camino. It's crazy to remember that I've been following the show since the beginning, and now I'm waiting for the final season.