Skip to content

Proof of concept: Generic OAuth - #162

Draft
RedFlames wants to merge 2 commits into
0x0ade:mainfrom
RedFlames:generic-oauth-providers
Draft

Proof of concept: Generic OAuth#162
RedFlames wants to merge 2 commits into
0x0ade:mainfrom
RedFlames:generic-oauth-providers

Conversation

@RedFlames

@RedFlames RedFlames commented Nov 6, 2024

Copy link
Copy Markdown
Collaborator

Still a bunch of things I'd have to clean up, but this is more like what I had in mind for supporting arbitrary OAuth2 providers

  1. Generate a random string for the OAuth2 "state" parameter, prefix it with the provider key (config name, e.g. "discord") and suffix with RSA signature of the random string (just a lil hack so that the state strings don't need to be tracked anywhere......)
  2. Allow OAuth2 providers configured like so:
OAuthProviders:
  discord:
    OAuthPathAuthorize: https://discord.com/oauth2/authorize
    OAuthPathToken: https://discord.com/api/oauth2/token
    OAuthScope: identify
    OAuthClientID: xxx
    OAuthClientSecret: xxx
    ServiceUserAPI: https://discord.com/api/users/@me
    ServiceUserJsonPathUid: $.id
    ServiceUserJsonPathName: $.['global_name','username']
    ServiceUserJsonPathPfp: $.avatar
    ServiceUserAvatarURL: https://cdn.discordapp.com/avatars/{0}/{1}.png?size=64
    ServiceUserAvatarDefaultURL: https://cdn.discordapp.com/embed/avatars/0.png

(YAML is absolute lunacy with how it doesn't serialize those JSONPaths as strings......)
3. Advantages: When requesting ServiceUserAPI which we don't know what exactly it returns, just try to parse it with config-provided JSONPaths 🙂
https://www.newtonsoft.com/json/help/html/QueryJsonSelectToken.htm
https://goessner.net/articles/JsonPath/

PS: Don't mind the change in client EmojiComponent...... I was lazy with my unstaged changes :) Moved that bit to #167

@RedFlames RedFlames removed the Client label Dec 21, 2024
@RedFlames RedFlames removed this from the server-next milestone Aug 26, 2025
@fantomitechno

Copy link
Copy Markdown

I tried running this PR with Twitch Oauth provider as a test, but I run into an issue

For the "OAuthPathToken" request, Discord wanted
image
this

in the body of the POST request but Twitch uses query parameters (even on POST request)
https://dev.twitch.tv/docs/authentication/getting-tokens-oauth/#authorization-code-grant-flow

@fantomitechno

Copy link
Copy Markdown

Another issues comes when trying to call the ServeiceUserAPI (still with Twitch),
the API requires the Client-Id to be provided along with the token
https://dev.twitch.tv/docs/api/get-started/#make-your-first-call

@RedFlames

RedFlames commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator Author

I tried running this PR with Twitch Oauth provider as a test, but I run into an issue

For the "OAuthPathToken" request, Discord wanted image this

in the body of the POST request but Twitch uses query parameters (even on POST request) https://dev.twitch.tv/docs/authentication/getting-tokens-oauth/#authorization-code-grant-flow

I'm confused by this. The POST request is being made with a FormUrlEncodedContent which is

A container for name/value tuples encoded using application/x-www-form-urlencoded MIME type.

Isn't that exactly the way Twitch also expects the request data? And with the same contents?

Getting the user info endpoint I guess should also work out with the JsonPaths...
Ah, I'm surprised they require the Client ID to be sent as a header 🤔

Not too hard to include that though, as an optional thing in some way.

What's going wrong with the token request when you run it?

@fantomitechno

fantomitechno commented Jul 16, 2026

Copy link
Copy Markdown

I'm confused by this. The POST request is being made with a FormUrlEncodedContent which is

A container for name/value tuples encoded using application/x-www-form-urlencoded MIME type.

Isn't that exactly the way Twitch also expects the request data? And with the same contents?

Ok it was a misunderstanding of the logs but now I am wondering how my old code worked, because I already used Twitch Oauth2 before and it is running fine with having the parameters as query parameters.

The only error is the Client ID as a header.

@fantomitechno

Copy link
Copy Markdown

I tried working on this PR to have something fully working

https://github.com/fantomitechno/CelesteNet/tree/generic-oauth-providers
based on your branch (with current main merged in it, to have dotnet 8.0 mostly)

For the Client ID in header, I chose to have a settings ProvideClientIdInHeaders, I am not satisfied with this but I do not know how to make it better and still generic.

I also added the changes to the Frontend:
image
(this is dynamic, I added an endpoint listing all available oauth method /api/available-oauth sending a list of string with the providers)

When authentified, I also added a via provider when connected
image

And finally, to make sure that there is no possibility for UID collision, I changed the UID format to be provider-id.
It requires a migration step for existing instance, but it is simple enough to just be a bulk addition of discord- in front of every UID.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants