使用Casdoor搭建用户身份管理平台

May 30, 2024

计划为博客加上认证(登录)注册能力,最初计划是使用Clerk之类的第三方平台,但是评估一圈之后还是决定采用Casdoor自己搭建。主要的评估因素包括以下几点:

  • 开发成本
  • 支持国内的QQ、Wechat等Provider
  • 价格:Clerk的免费版功能限制挺多的,比如仅允许3个Provider,而现在还没有付费版的诉求。Pro版价格是$25,已经超过我腾讯云机器的价格了。
  • 开源:个人偏好,不要绑定在某一个特定平台。

Casdoor的搭建流程并不复杂,后端使用GO实现,理论上资源消耗应该也不大,遂决定在我的vps上安装。

介绍

Casdoor是一个开源的身份和访问管理(IAM)/单点登录(SSO)平台。其主要特性包括:

  • 前后端分离的架构,前端使用react,后端使用 Go 语言开发,Casdoor 支持高并发,提供基于Web的用户管理 UI,并支持中、英等多种语言
  • Casdoor 支持 Github, Google, QQ, WeChat, Facebook, Gitee 等第三方应用程序登录,并支持使用插件扩展第三方登录
  • 使用 Casbin 基于授权管理,Casdoor 支持 ACL, RBAC, ABAC, RESTful 等访问控制模型
  • 个性化的注册、登录和忘记密码页面。支持手机验证码、邮件验证码、找回密码等功能
  • 使用阿里云、腾讯云、七牛云提供的图片CDN云存储
  • Casdoor 支持使用 db 同步方法与现有系统的集成,用户可以顺利过渡到Casdoor
  • Casdoor 支持的主流数据库: MySQL, SQL Server, PostgreSQL 等, 并支持扩展插件的新数据库

安装

官方提供了多种安装方式,包括docker安装、本地服务端安装等,参考官方文档。

我采用的是本地server安装的方式,大致流程:

  1. git clone 后编译前端web。
  2. 编译后端go sever。此时已经已经将前后端打包成一个可执行文件了。
  3. 创建mysql database。
  4. 修改 conf/app.conf 配置文件中的DB配置
  5. 使用pm2启动服务。
  6. 配置Nginx、分配单独的子域名以及SSL证书。

注意点

  • 不支持path:所以需要有独立域名。我使用的自己域名下的独立子域名。后续的SMTP也使用此域名。
  • 编译前端react时内存消耗较大,我的4G的vps竟然有点吃力。看官方文档应该需要2G左右,禁用sourcemap后才编译通过。

配置

使用前登录管理台,做了一些简单的配置。

基础配置

  1. 安全措施:修改管理员默认秘钥,禁止默认app注册。
  2. 新增orgnization、application,供个人博客使用。
  3. 注册了github provider。
  4. application中去掉了一些不必要的信息,比如手机号,简化注册流程。
  5. 登录页样式做了一些简单的调整。

SMTP

为了提供注册能力,需要提供一个可用的EMail Provier,用于验证邮箱以及找回密码登。对比一下官方文章中的几种Email Provider。

sendgrid

  • 免费版:免费额度 100次/天。
  • Essentials版:$20/月。

Azure

  • 按使用量

brevo

  • 免费版:免费额度300次/天
  • Starter:5000/月
  • 注册有地区限制

尝试一圈后放弃,注册流程太麻烦了,国内手机没法使用。最终看了腾讯云的SMTP服务并不贵,于是按照文档安装完毕。

💡
增加email provider时遇到一个bug:需要先保存然后才能测试STMP connnection的可用性。否则一直会有个奇怪的无法连接错误。原因是服务端没有使用页面上填写stmp server信息进行验证,已经反馈给官方。

其他

增加了部分Provider,比如GIT,用于支持第三方账号的直接登录。后续再慢慢增加其他类型。

使用

按照官方的列子,Next项目使用相关的改动点,包括以下部分:

  1. 增加认证拦截中间件:未认证用户拦截跳转到登录页page。
Loading...
  1. 增加登录page:这里的登录页面不需要我们实现,直接跳转到casdoor的页面即可。可以理解为casdoor帮助我们完成了认证(登录)、注册的能力,然后将认证成功的用户信息(code)通过指定的redirec参数t地址返回给到我们。
Loading...

上面的client、orgnization、app等需要在casdoor上面自行提前分配好。

  1. 用户在casdoor页面上完成注册、认证之后,casdoor会将认证 code 通过redirect的方式给到应用(即上面的redirectPath)。应用需要将code换取为 access_token ,并通过access_token获取用户详细信息,存放到cookie中。
Loading...

获取到的票据包括以下字段

Loading...

上面只是演示了OIDC基础使用流程,使用了session cookie来存储,如果需要持久化存储,还有一些关于票据安全的优化点需要考虑。

票据安全

cookie有效期

上面设置cookie使用的是session cookie,即关闭浏览器cookie就会丢失,下次访问时需要重新认证,但是这不能阻挡用户故意存储票据用于下次访问。理论上accesstoken是有个过期时间的。在casdoor服务端上配置,这里需要有一定的机制来保证用户的票据在超过过期时间expires_in之后无效。

cookie内容合法性

上面的middleware仅仅校验了cookie中是否存在user信息,并没有校验用户的合法性。页面是可以篡改cookie数据的,比如将用户id、name替换,如果后端直接使用cookie中的user信息,就会有安全风险。

更加合适的做法是将accesstoken当做票据,并在middleware中校验accesstoken的有效性。使其承担起接入层的作用。accesstoken可以访问cosdoor去校验,或者在业务服务端存储,基本不可能伪造(但是也有被共享的可能)。

参考Casnode示例。使用了session来存储ParseJwtToken()的claim结果,里面包换了accesstoken以及用户信息。

Loading...

票据更新

理论上accesstoken的过期时间不应该太长,比如2小时。然后通过票据刷新接口定期刷新accesstoken,避免使用过程中的泄露。

吐槽

在自己的接入SDk的过程中,发现一些小的问题。

  1. SDK参数各异:比如js版前后端版本的SDK,url、org都能有两种写法
Loading...
Loading...
  1. SDK鉴权方式差异,在官方文档中,前后端鉴权所需的参数还挺大的。在我看来使用的目的相同,都是取用户资料,为何后端还需要cert、secret key等,而前端sdk啥也不用?cert、secret这种是否有必要并存。
  2. SDK能力不完善。个人项目是使用nextjs,安全考虑,期望是将accsstoken获取、解析放在后端,避免jwt透传。提供的next SDK仅在client component下可用,server端根本没办法使用。转而使用node版本的SDK,发现在next下无法使用(依赖的 jsonwebtoken 在next 环境不兼容)。

总结

以上就是casdoor的用户认证基础流程,基础的用户认证管理接入还是挺简单的。casdoor还提供了不少其他能力,包括商品管理&教育、用户群组管理。

 

 

See all postsSee all posts