Original link: https://oldj.net/article/2023/06/27/discourse-with-django-oauth2/
Recently set up a Discourse forum, trying to log in with another account in the existing Django system. Stepped on some small pits, let’s record the process below.
The content of this article is based on the following software and versions:
- Discourse 3.1.0.beta5
- Django 4.2.2
- Django Oauth Toolkit 2.3.0
Install Discourse
The installation of Discourse is relatively smooth, basically follow the official instructions. It is better to use a machine without web service, that is, ports 80 and 443 are not occupied, otherwise there will be some troubles.
I managed the domain name through Cloudflare. At the beginning, I kept encountering “ERR_TOO_MANY_REDIRECTS” error. After querying, I found that it was because the “SSL/TLS encryption mode” needs to use the “full” mode, and the default “flexible” mode cannot be used.
For the email sending service, I first tried Alibaba Cloud’s email push service, and then chose Mailjet ‘s service based on the recommendation on the Discourse installation instructions page. Both Alibaba Cloud mail push and Mailjet can support it, and both have a free quota of 200 emails per day, which is enough for small applications.
Discourse preparation
Discourse has built-in third-party logins such as Google, Facebook, GitHub, Twitter, etc., just configure and enable them in the settings. However, if you want to integrate a custom OAuth2 login service, you also need to install an additional plug-in discourse-oauth2-basic maintained by the official.
The plug-in installation method is to modify the app.yml file under the /var/discourse/containers
directory on the Discourse server, find the hooks
field in it, and add the git warehouse address of the plug-in to cmd
, as shown in the following code:
hooks: after_code: - exec: cd: $home/plugins cmd: - git clone https://github.com/discourse/docker_manager.git - git clone https://github.com/discourse/discourse-oauth2-basic.git
Note that docker_manager.git
is available by default, and discourse-oauth2-basic.git
in the last line is newly added.
After the addition is complete, execute the following command in the /var/discourse
directory:
./launcher rebuild app
It takes a few minutes to execute the command, and the new configuration will take effect after completion.
Django-ready
Django does not support OAuth2 login by default, but there is a mature third-party plug- in Django OAuth Toolkit to solve this problem, just install it according to the official documentation.
After the installation is complete and Django OAuth Toolkit is introduced in settings.py
, remember to add the following configuration:
OAUTH2_PROVIDER = { # 其他配置项... 'PKCE_REQUIRED': False, }
Django OAuth Toolkit enables PCKE by default, but currently Discourse’s OAuth2 plug-in does not support PKCE. If you do not set PKCE_REQUIRED
in Django to False
, you may encounter invalid_request
error when logging in later. The specific error description is “Code challenge required.”
In addition, you also need to specify an access address for the Django OAuth Toolkit service, for example, add a record similar to the following in url.py
of the site:
path('oauth/', include('oauth2_provider.urls', namespace='oauth2_provider')),
Then you can access the OAuth2 interface through https://YOUR_DJANGO_SITE/oauth/*
.
Finally, you need to prepare a page in the Django site, which can be accessed using OAuth2 authorization. The content of the page is user information displayed in JSON format, so that Discouse can read user name, Email and other information after successful login.
Django configuration
Add a new record in “Django OAuth Toolkit” → “Application” in the Django admin background. The key points to fill in are as follows:
- Client id : Use the default or a value you specify
- User : leave blank
- Redirect uris : fill in the value of
https://YOUR_DISCOURSE_SITE/auth/oauth2_basic/callback
, you need to replaceYOUR_DISCOURSE_SITE
in the middle with the domain name of your Discourse site - Client type : select “Confidential”
- Authorization grant type : select “Authorization code”
- Client secret : Use the default value or the value you specify. Note that if you decide to use the default value, you need to copy the value when you add the record for the first time, because you will only see the hashed value when you open this record later value
- Name : Just choose a name that is easy to remember or recognize, such as “Discourse”
- Skip authorization : This item is used to control whether to show the user a confirmation page to authorize the login after successful login. It is recommended to check it, because the default style of that page is very simple, which affects the experience
The rest of the items not mentioned can use the default value.
Discourse configuration
Finally, go back to the configuration on the Discourse side.
On the plug-in management page of Discourse, you can see the list of installed plug-ins, click the setting button of discourse-oauth2-basic
plug-in to enter the corresponding setting page.
Of course, you can also see related settings under the “Login” panel of the general settings, but there are many options in that panel. If you only want to set OAuth2 related options, you can click the settings button of the plugin to filter out irrelevant items.
The following are the main setting items and descriptions.
- oauth2 enabled : Check this to enable OAuth2 login
- oauth2 client id : the Client id set in the Django background
- oauth2 client secret : the Client secret set in the Django background
- oauth2 authorize url : OAuth2 authorization address of Django background
- oauth2 token url : the address where Django obtains Token in the background
Among them, oauth2 authorize url and oauth2 token url are related to your Django configuration. If the prefix of your configured OAuth2 service is /oauth/
, the corresponding addresses are as follows:
# oauth2 authorize url https://YOUR_DJANGO_SITE/oauth/authorize/ # oauth2 token url https://YOUR_DJANGO_SITE/oauth/token/
Select POST
for the subsequent oauth2 token url method , and leave blank or use the default values for the subsequent oauth2 callback user id path and oauth2 callback user info paths .
Below are the fields related to oauth2 fetch user details . You need to prepare a page on the Django site first. For example, the page is https://YOUR_DJANGO_SITE/api/account/info
, and the returned content is as follows:
{ "data": { "uid": "xxx", "username": "my_name", "email": "[email protected]" // ...... } }
You can also add more fields, such as the user’s full name, avatar image address, whether the Email is verified, and so on.
Then, fill in the relevant fields in the following fields. for example:
- oauth2 user json url : fill in
https://YOUR_DJANGO_SITE/api/account/info
- oauth2 json user id path : fill in
data.uid
- oauth2 json user name path : fill in
data.username
- oauth2 json email path : fill in
data.email
Fill in the rest of the fields as needed.
If all goes well, your Discourse site will be ready to log in with your Django site account.
This article is transferred from: https://oldj.net/article/2023/06/27/discourse-with-django-oauth2/
This site is only for collection, and the copyright belongs to the original author.