Skip to content

Instantly share code, notes, and snippets.

@aaronpk
Last active June 26, 2025 18:02
Show Gist options
  • Save aaronpk/5846789 to your computer and use it in GitHub Desktop.
Save aaronpk/5846789 to your computer and use it in GitHub Desktop.
Added WebFinger support to my email address using one rewrite rule and one static file.
[[email protected] www]$ cat .htaccess
RewriteEngine on
RewriteCond %{QUERY_STRING} resource=acct:(.+)
RewriteRule ^\.well-known/webfinger /profile/%1? [L]
[[email protected] www]$ cat profile/[email protected]
{
"subject": "acct:[email protected]",
"links": [
{
"rel": "http://webfinger.net/rel/avatar",
"href": "http://aaronparecki.com/images/aaronpk.png"
},
{
"rel": "http://webfinger.net/rel/profile-page",
"href": "http://aaronparecki.com/"
},
{
"rel": "me",
"href": "http://aaronparecki.com/"
}
]
}
@sorenpeter
Copy link

Should there be a file or folder called webfinger in the .well-known folder?

@Dan-Q
Copy link

Dan-Q commented Apr 11, 2023

@sorenpeter asked:

Should there be a file or folder called webfinger in the .well-known folder?

No, the RewriteCond and RewriteRule tells Apache, "when somebody asks for /.well-known/webfinger?resource=acct:SOMETHING, instead serve them /profile/SOMETHING". This then allows you to store static files in /profile/... for each user account represented by webfinger and it pretty-much "just works".

If the rules are working properly, you'll never need an actual file at /.well-known/webfinger.

@steelman
Copy link

steelman commented Nov 19, 2024

Alas according to the documentation RewriteMap cannot be declared in a per-directory context including .htaccess. So one probably need to name their json files with %40 instead of @ or symlink them because some clients (e.g. Mastodon) send unescaped requests. This also requires to support both : and %3a

RewriteCond %{QUERY_STRING} resource=acct(:|%3[Aa])([^&]+)
RewriteRule ^\.well-known/webfinger /webfinger/%2? [NE,T=application/jrd+json;charset=UTF-8]

@roseeng
Copy link

roseeng commented May 26, 2025

A lot of good info here, unfortunately not in a copy-pastable format (steelman's comment put the profiles in a different subfolder and fmarier accidentally let the dot stay unescaped). Also, with my current provider, it is better to put folder-specific directives in that folder instead of a directive.

So here is my attempt at combining all good ideas from above:

Create a folder called profile
In it, create a .htaccess file with the following contents:

DefaultType application/json
Header set Access-Control-Allow-Origin: "*"

Also create a file for your profile (named [email protected]).
Fill it with the suitable json (no point in me giving you an example).

Then, in your root folder, add the following at the beginning of your .htaccess file:

RewriteEngine on
RewriteCond %{QUERY_STRING} resource=acct(:|%3[Aa])([^&]+)
RewriteRule ^\.well-known/webfinger /profile/%2? [NE,T=application/jrd+json;charset=UTF-8]

If your base folder needs it (i.e. you try it but get a 404) , change the rewrite rule to

RewriteRule ^/\.well-known/webfinger /profile/%2? [NE,T=application/jrd+json;charset=UTF-8]

And last, you try it by navigating to https://your-domain.com/.well-known/webfinger?profile=acct:[email protected]
To double-check that url-encoded calls will work, also try fetching https://your-domain.com/.well-known/webfinger?profile=acct%3Ayour-name%40your-domain.com

@fmarier
Copy link

fmarier commented Jun 26, 2025

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