Hello!
I have been looking at setting up a Flarum forum alongside a Django (Wagtail) based site. As the main site has user accounts I wanted to be able to re-use these on the Flarum side. This turned out to be relatively easy to set up using the FoF Passport extension, which is intended to communicate with Laravel Passport.
The first step is to add the following extension into your Flarum installation: https://discuss.flarum.org/d/5203-fof-passport-the-laravel-passport-oauth-extension
Thanks to @Sanguine this extension is now also available on FreeFlarum.
Flarum
Once installed you'll see the settings dialog
The bits in red are your secret key, keep them private. The top 3 fields need to be filled with URLs to your Django app install (covered in the next bit). The OAuth scopes should be "read" and the Label for the button can be anything you like. This is what is shown on the button that's used to login.
Django
On the Django side you need to add an OAuth provider. Thankfully someone else has done all the work of creating one, which is available here https://django-oauth-toolkit.readthedocs.io/en/latest/tutorial/tutorial_01.html#create-an-oauth2-client-application ...you can follow this installation guide as-is.
In my case I changed the OAuth URL definition to
path("oauth/", include('oauth2_provider.urls', namespace='oauth2_provider')),
...which is why the first two URLs on the config start with oauth/ not o/. Do what you like here. You also don't want to run in production with CORS_ORIGIN_ALLOW_ALL = True
so instead set the following with a list of your allowed domains.
CORS_ORIGIN_WHITELIST = [
"https://<my website>",
"http://<my flarum site>",
]
Once setup, create an Application in your Django Admin (or from the shell) and add the redirect URI. You want to set the applciation to "confidential", grant type to "authorization-code" and fill in the client ID and secret from your Flarum settings (these are automatically generated for you). You can also set skip_authorisation to True if you don't want users to be asked whether they wanted to link accounts (may not actually be necessary, never saw this happen).
This has taken care of the first two URLs, but what about the third? The third is a Passport-specific endpoint for returning data about a user. We need to define our own endpoint for this, here is an example view using django rest framework.
@api_view(['GET'])
def passport_user(request):
bearer = request.META.get('HTTP_AUTHORIZATION')
if not bearer:
raise Http404("No authorization in headers")
token = bearer.split()[1] # Retreive code
# If the code is non-existing/expired, this will fail.
access = AccessToken.objects.get(token=token)
user = access.user
return Response({
'id': user.id,
'email': user.email,
'name': user.get_full_name(),
})
Set up an URL for this view and add that into your Flarum config as the third URL. You should now find that the login works! When clicking Login in Flarum you'll see the login window, plus the new button. Clicking this will open a modal window with your parent sites login forum (or if you're already logged in there, redirecting back). If the user is not set up Flarum will then prompt you to provide a username to use on the forum.
As far as I know there is no way to remove the normal login currently, but you can hide the form by using custom CSS rules, leaving only the SSO button. e.g.
.LogInModal .Form, .LogInModal .Modal-footer { display: none ;}
.LogInButtons {
width: 100%;
}
.LogInButtons .Button {
color: #FEFCFD !important;
background: #FE4A49;
border: solid #b13028;
border-width: 0 0px 3px 0;
font-size: 1.25em;
text-shadow: 0px 2px 5px rgba(0, 0, 0, 0.2);
}
Of course, only do this once you know it's working!
Hope that helps, feel free to ask if you need to troubleshoot anything. I've probably been through the same problem at least once.