IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    Discourse 集成 Django 登录

    oldj\'s blog发表于 2023-06-27 09:41:00
    love 0

    最近搭建了一个 Discourse 论坛,尝试使用另一个已有的 Django 系统中的账号进行登录。踩了一些小坑,下面记录一下过程。

    本文内容基于以下软件以及版本:

    • Discourse 3.1.0.beta5
    • Django 4.2.2
    • Django Oauth Toolkit 2.3.0

    安装 Discourse

    Discourse 的安装比较顺利,基本上按官方说明操作即可。最好使用一台没有 Web 服务的机器,即 80 和 443 端口没有被占用,否则会有一些麻烦。

    域名我是通过 Cloudflare 管理的,一开始一直遇到“ERR_TOO_MANY_REDIRECTS”错误,查询之后发现是因为“SSL/TLS 加密模式”需要使用“完全”模式,不能使用默认的“灵活”模式。

    邮件发送服务,先是试了下阿里云的邮件推送,后来又根据 Discourse 安装说明页面的推荐,选了 Mailjet 的服务。阿里云邮件推送和 Mailjet 都可以支持,且两者每天都有 200 封免费额度,对小应用来说足够了。

    Discourse 准备

    Discourse 内置了 Google、Facebook、GitHub、Twitter 等第三方登录,只需在设置中配置开启即可。不过如果想集成自定义 OAuth2 登录服务,还需要安装一个由官方维护的额外插件 discourse-oauth2-basic。

    插件安装方式为修改 Discourse 服务器上 /var/discourse/containers 目录下的 app.yml 文件,找到其中 hooks 字段,将插件的 git 仓库地址添加到 cmd 中,如下面的代码所示:

    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
    

    注意其中的 docker_manager.git 是默认有的,最后一行的 discourse-oauth2-basic.git 则是新添加的。

    添加完成之后,在 /var/discourse 目录下执行以下命令:

    ./launcher rebuild app
    

    命令的执行过程需要几分钟,完成之后新的配置就生效了。

    Django 准备

    Django 默认不支持 OAuth2 登录,不过有一个成熟的第三方插件 Django OAuth Toolkit 解决了这个问题,根据官方文档安装即可。

    安装完成并在 settings.py 中引入 Django OAuth Toolkit 之后,记得添加下面一项配置:

    OAUTH2_PROVIDER = {
      # 其他配置项...
      'PKCE_REQUIRED': False,
    }
    

    Django OAuth Toolkit 默认启用 PCKE,但目前 Discourse 的 OAuth2 插件还不支持 PKCE,如果不把 Django 中的 PKCE_REQUIRED 设为 False,后面登录时可能会遇到 invalid_request 错误,具体错误描述为“Code challenge required.”。

    另外,也需要为 Django OAuth Toolkit 服务指定一个访问地址,比如在站点的 url.py 中添加类似下面的记录:

    path('oauth/', include('oauth2_provider.urls', namespace='oauth2_provider')),
    

    之后便可以通过 https://YOUR_DJANGO_SITE/oauth/* 访问 OAuth2 接口。

    最后,还需要在 Django 站点中准备一个页面,可以使用 OAuth2 授权访问,页面内容为以 JSON 格式显示的用户信息,以便 Discouse 登录成功后读取用户名、Email 等信息。

    Django 配置

    在 Django 管理后台的“Django OAuth Toolkit” → “Application”中新添加一条记录。各项填写要点如下:

    • Client id:使用默认值或你指定的值
    • User:留空
    • Redirect uris:填写形如 https://YOUR_DISCOURSE_SITE/auth/oauth2_basic/callback 的值,你需要把中间的 YOUR_DISCOURSE_SITE 替换为你的 Discourse 站点的域名
    • Client type:选择“Confidential”
    • Authorization grant type:选择“Authorization code”
    • Client secret:使用默认值或你指定的值,注意如果你决定使用默认值,需要在第一次添加记录时将值复制出来,因为后面再打开这条记录时将只能看到哈希后的值
    • Name:取一个容易记忆或识别的名字即可,比如“Discourse”
    • Skip authorization:此项用于控制在登录成功之后,要不要给用户显示一个是否授权登录的确认页面。建议勾选,因为那个页面默认样式很简陋,影响体验

    其余没有提到的项使用默认值即可。

    Discourse 配置

    最后,再回到 Discourse 这边的配置。

    在 Discourse 的插件管理页面,可以看到安装的插件列表,点击 discourse-oauth2-basic 插件的设置按钮可进入对应的设置页面。

    当然,你也可以在总设置的“登录”面板下看到相关的设置,不过那个面板选项很多,如果只想设置 OAuth2 相关的选项,可以点击插件的设置按钮以过滤掉无关项。

    以下是主要设置项以及说明。

    • oauth2 enabled:选中此项以启用 OAuth2 登录
    • oauth2 client id:即 Django 后台设置的 Client id
    • oauth2 client secret:即 Django 后台设置的 Client secret
    • oauth2 authorize url:Django 后台的 OAuth2 授权地址
    • oauth2 token url:Django 后台获取 Token 的地址

    其中 oauth2 authorize url、oauth2 token url 和你的 Django 配置有关,如果你配置的 OAuth2 服务的前缀为 /oauth/ ,则对应的地址如下:

    # oauth2 authorize url
    https://YOUR_DJANGO_SITE/oauth/authorize/
    
    # oauth2 token url
    https://YOUR_DJANGO_SITE/oauth/token/
    

    之后的 oauth2 token url method 选择 POST,再之后的 oauth2 callback user id path 和 oauth2 callback user info paths 留空或使用默认值即可。

    再下面则是 oauth2 fetch user details 相关的字段,你需要先在 Django 站点准备好一个页面,比如页面为 https://YOUR_DJANGO_SITE/api/account/info,返回内容形如:

    {
      "data": {
        "uid": "xxx",
        "username": "my_name",
        "email": "me@myemail.com"
        // ......
      }
    }
    

    还可以添加更多字段,比如用户全名、头像图片地址、Email 是否已验证等等。

    随后,将相关字段填写到接下来的字段中即可。比如:

    • oauth2 user json url:填写 https://YOUR_DJANGO_SITE/api/account/info
    • oauth2 json user id path:填写 data.uid
    • oauth2 json user name path:填写 data.username
    • oauth2 json email path:填写 data.email

    其余字段根据需要填写即可。

    如果一切顺利,你的 Discourse 站点就可以使用 Django 站点的账号登录了。



沪ICP备19023445号-2号
友情链接