ruoyi cloud集成casdoor

本文介绍如何在Ruoyi-Cloud项目中集成Casdoor单点登录系统,包括环境搭建、Casdoor部署及配置、前端与后端的修改步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        之前写过一篇关于ruoyi cloud集成cas的但是使用的apereo的单点登录,该应用的文档都是英文文档,尝试一下集成casdoor,其官方文档比较详细。

考虑到有些小伙伴上git不方便,需要用到的代码和Windows工具,都在这了        

1、环境搭建

    我沿用了之前的服务器,所以在官网下载Go 1.9的windows安装包

    下载msi,傻瓜式安装,cmd输入go version,出现版本号,收工

     后两项就不写了,网上太多

2、casdoor部署

创建文件夹,右键git bash

 git clone https://github.com/casdoor/casdoor.git

下载完成代码后,进入casdoor-master文件夹,修改conf,修改app.conf文件,datasourcename:数据库的用户名,密码,地址,dbName:数据库名

appname = casdoor
httpport = 8000
runmode = dev
SessionOn = true
copyrequestbody = true
driverName = mysql
dataSourceName = root:123456@tcp(localhost:3306)/
dbName = casdoor
tableNamePrefix =
showSql = false
redisEndpoint =
defaultStorageProvider =
isCloudIntranet = false
authState = "casdoor"
socks5Proxy = "127.0.0.1:10808"
verificationCodeTimeout = 10
initScore = 2000
logPostOnly = true
origin = "https://door.casdoor.com"
staticBaseUrl = "https://cdn.casbin.org"

进入cmd,切换国内代理

go env -w GOPROXY=https://goproxy.cn

使用命令运行后端

go run main.go

进入web文件夹,cmd,下载yarn

npm install --global yarn

验证yarn是否安装完成

yarn --version

安装前端依赖

yarn install

前端运行

yarn start

3配置casdoor

1、新建组织,将密码类型呢改成bcrypt,并开启软删除

2、新建同步器,配置数据库密码,修改表列 

3、保存和同步,查看若依的用户是否存在

4、新建应用和证书,在新建的应用中,选择新创建的证书,在重定向urls内添加

http://localhost:81/login

4修改若依前端

1、安装vue-sdk

npm i casdoor-vue-sdk --save

2、执行指令

npx vue-demi-fix

3、修改main.js


//新增
import Casdoor from 'casdoor-vue-sdk'
import VueCompositionAPI from '@vue/composition-api'
const config = {
  serverUrl: "你的casdoor路径",
  clientId: "客户端id",
  organizationName: "组织名称",
  appName: "应用名称",
  redirectPath: "/login(重定向回来的路径)",
};
Vue.use(VueCompositionAPI)
Vue.use(Casdoor,config)

//修改
new Vue({
  el: '#app',
  router,
  store,
  render: h => h(App)
}).$mount('#app')

4、修改login.vue(直接替换)

<template>
  <div class="login">
    <el-form ref="loginForm"  class="login-form">
      <h3 class="title">若依后台管理系统</h3>

    </el-form>
    <!--  底部  -->
    <div class="el-login-footer">
      <span>Copyright © 2018-2022 ruoyi.vip All Rights Reserved.</span>
    </div>
  </div>
</template>

<script>
import { getCodeImg } from "@/api/login";
import Cookies from "js-cookie";
import { encrypt, decrypt } from '@/utils/jsencrypt'

export default {
  name: "Login",
  data() {
    return {
      codeUrl: "",
      loginForm: {
        code: "",
        state: ""
      },

      loading: false,
      // 验证码开关
      captchaEnabled: false,
      // 注册开关
      register: true,
      redirect: undefined
    };
  },
  watch: {
    $route: {
      handler: function(route) {
        this.redirect = route.query && route.query.redirect;
      },
      immediate: true
    }
  },
  created() {
    /*this.getCode();
    this.getCookie();*/

      let url = window.document.location.href//get url
      let u = new URL(url);
      this.loginForm.code = u.searchParams.get('code')//get code and state
      this.loginForm.state = u.searchParams.get('state')
      if(this.loginForm.code!=null&&this.loginForm.state!=null){//if code and state is null, execute handleLogin
        this.handleLogin()
      }else{
        window.location.href = this.getSigninUrl();
      }

  },
  methods: {
    handleLogin() {
      console.log("进入handleLogin",this.loginForm);
      this.$store.dispatch("Login",this.loginForm).then(()=>{
        this.$router.push({path:this.redirect || "/"}).catch(()=>{});
      }).catch(()=>{
        this.loading = false;
      })
    }
  }
};
</script>

<style rel="stylesheet/scss" lang="scss">
.login {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
  background-image: url("../assets/images/login-background.jpg");
  background-size: cover;
}
.title {
  margin: 0px auto 30px auto;
  text-align: center;
  color: #707070;
}

.login-form {
  border-radius: 6px;
  background: #ffffff;
  width: 400px;
  padding: 25px 25px 5px 25px;
  .el-input {
    height: 38px;
    input {
      height: 38px;
    }
  }
  .input-icon {
    height: 39px;
    width: 14px;
    margin-left: 2px;
  }
}
.login-tip {
  font-size: 13px;
  text-align: center;
  color: #bfbfbf;
}
.login-code {
  width: 33%;
  height: 38px;
  float: right;
  img {
    cursor: pointer;
    vertical-align: middle;
  }
}
.el-login-footer {
  height: 40px;
  line-height: 40px;
  position: fixed;
  bottom: 0;
  width: 100%;
  text-align: center;
  color: #fff;
  font-family: Arial;
  font-size: 12px;
  letter-spacing: 1px;
}
.login-code-img {
  height: 38px;
}
</style>

5、修改user.js的login方法

Login({ commit }, userInfo) {
      const code = userInfo.code
      const state = userInfo.state
      return new Promise((resolve, reject) => {
        login(code, state).then(res => {
          let data = res.data
          setToken(data.access_token)
          commit('SET_TOKEN', data.access_token)
          setExpiresIn(data.expires_in)
          commit('SET_EXPIRES_IN', data.expires_in)
          resolve()
        }).catch(error => {
          reject(error)
        })
      })
    },

6、修改api下面的login.js

export function login(code,state) {
  return request({
    url: '/auth/login',
    headers: {
      isToken: false
    },
    method: 'post',
    data: { code,state }
  })
}

可以尝试运行,是否会跳转,是否能返回code和state

5、修改若依后端

1、导入依赖

<dependency>
            <groupId>org.casbin</groupId>
            <artifactId>casdoor-spring-boot-starter</artifactId>
            <version>1.2.0</version>
</dependency>

2、新建实体CodeBody

package com.ruoyi.auth.form;


public class CodeBody {
    private String code;
    private String state;

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    @Override
    public String toString() {
        return "CodeBody{" +
                "code='" + code + '\'' +
                ", state='" + state + '\'' +
                '}';
    }
}

3、修改tokenController,login方法

    @PostMapping("login")
    public R<?> callback(@RequestBody CodeBody code) {//we should define a CodeBody entity which have code and state
        String token = casdoorAuthService.getOAuthToken(code.getCode(), code.getState());
        CasdoorUser casdoorUser = casdoorAuthService.parseJwtToken(token);
        if(casdoorUser.getName()!=null){
            String casdoorUserName = casdoorUser.getName();
            if(sysLoginService.getUserByCasdoorName(casdoorUserName)==null){//if database haven't this user
                // add this user into database
                sysLoginService.casdoorRegister(casdoorUserName);
            }
        }
        LoginUser userInfo = sysLoginService.casdoorLogin(casdoorUser.getName());//get this user's information by database
        return R.ok(tokenService.createToken(userInfo));
    }

4、sysloginService新增三个方法

public LoginUser casdoorLogin(String username){
        // execute user
        R<LoginUser> userResult = remoteUserService.getUserInfo(username, SecurityConstants.INNER);
        if (R.FAIL == userResult.getCode())
        {
            throw new ServiceException(userResult.getMsg());
        }

        if (StringUtils.isNull(userResult) || StringUtils.isNull(userResult.getData()))
        {
            recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "this user is not exist");
            throw new ServiceException("user:" + username + " is not exist");
        }
        LoginUser userInfo = userResult.getData();
        SysUser user = userResult.getData().getSysUser();
        if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
        {
            recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "sorry, your account was deleted");
            throw new ServiceException("sorry, your account:" + username + " was deleted");
        }
        if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
        {
            recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "your account is disabled, you can contact admin ");
            throw new ServiceException("sorry, your account:" + username + " is disabled");
        }
        recordLogService.recordLogininfor(username, Constants.LOGIN_SUCCESS, "login successfully");
        return userInfo;
    }
    public String getUserByCasdoorName(String casdoorUsername){
        R<LoginUser> userResult = remoteUserService.getUserInfo(casdoorUsername, SecurityConstants.INNER);
        if (StringUtils.isNull(userResult) || StringUtils.isNull(userResult.getData()))
        {
            //if this user is not in RuoYi-Cloud database and casdoor have this user, we should create this user in database
            return null;
        }
        String username = userResult.getData().getSysUser().getUserName();
        return username;
    }
    public void casdoorRegister(String username){
        if (StringUtils.isAnyBlank(username))
        {
            throw new ServiceException("User must fill in");
        }
        SysUser sysUser = new SysUser();
        sysUser.setUserName(username);
        sysUser.setNickName(username);
        R<?> registerResult = remoteUserService.registerUserInfo(sysUser, SecurityConstants.INNER);
        System.out.println(registerResult);
        if (R.FAIL == registerResult.getCode())
        {
            throw new ServiceException(registerResult.getMsg());
        }
        recordLogService.recordLogininfor(username, Constants.REGISTER, "register successfully");
    }

5、bootstrap.yml内新增casdoor配置

server: 
  port: 36000
casdoor:
  endpoint: casdoor地址
  client-id: 客户端id
  client-secret: 客户端密钥
  certificate: 证书名称
  jwtPublicKey: 证书公钥,注意拷下来的公钥,每一行结尾加\n\,如"-----BEGIN CERTIFICATE-----\n\
  MIIE2TCCAsGgAwIBAgIDAeJAMA0GCSqGSIb3DQEBCwUAMCYxDjAMBgNVBAoTBWFk\n\
 .
 .
 .
  teANTdYzr6IIZiweG1/vvAXIk4HfjyVtOvxYAa6tfe0hpXDhCcqsO2ekpm0H\n\
  -----END CERTIFICATE-----"
  organization-name: 组织名称
  application-name: 应用名称

### Casdoor 开源身份认证框架使用指南 Casdoor 是一个基于 OAuth 2.0/OIDC 的开源集中式身份验证/单点登录 (SSO) 平台,提供了丰富的功能和灵活的集成方式[^1]。以下是关于如何安装、配置和集成 Casdoor 的详细说明。 #### 安装 Casdoor 要开始使用 Casdoor,需先完成安装过程。可以通过以下两种方式进行安装: 1. **Docker 安装** 使用 Docker 是最简单的方式之一。运行以下命令即可启动 Casdoor 和其依赖的服务: ```bash docker pull casbin/casdoor docker run -d --name casdoor -p 8000:8000 casbin/casdoor ``` 2. **手动安装** 如果不希望通过 Docker 运行 Casdoor,则可以选择手动部署。具体步骤如下: a. 下载并解压最新版本的 Casdoor 源码文件。可以从 GitHub 上获取最新的发布包[^3]。 b. 确保已安装 Go 编译器(推荐版本 >= 1.16)。编译源代码后执行二进制文件即可启动服务。 #### 配置 Casdoor 成功安装后,需要对 Casdoor 进行基本配置以满足实际需求。 1. **数据库设置** 默认情况下,Casdoor 使用 SQLite 数据库存储数据。如果希望切换至其他类型的数据库(如 MySQL 或 PostgreSQL),则需要修改 `conf/config.yml` 文件中的相关内容。例如: ```yaml databaseType: mysql dataSourceName: root:password@(localhost:3306)/casdoor?charset=utf8&parseTime=True&loc=Local ``` 2. **初始化管理员账户** 访问 Casdoor 提供的 Web UI 页面(通常是 http://localhost:8000),按照提示创建初始超级管理员账号。此操作仅限于首次访问时有效。 3. **自定义域名绑定** 若要让外部网络能够正常访问您的 Casdoor 实例,请确保服务器防火墙开放相应端口,并将域名解析指向该 IP 地址。 #### 集成 Casdoor 到应用程序 为了实现 SSO 功能或将用户管理系统迁移到 Casdoor 中,通常需要将其与其他系统对接起来。下面列举了几种常见的集成方案及其对应的实现方法。 1. **通过 RESTful API 调用** Casdoor 支持标准 HTTP 请求形式调用接口来处理用户的注册、登录等功能。官方文档中列出了详细的 API 参数列表及返回值结构描述[^1]。开发者可以根据这些信息快速编写客户端逻辑并与后台交互。 2. **利用 SDK 工具简化开发流程** 对于某些特定编程语言而言,可以直接引入由社区维护好的第三方库作为辅助工具。比如 Python 用户可以尝试 pip install python-casdoor 来减少重复编码工作量;而对于 JavaScript 前端工程师来说也有类似的 npm 包可用。 3. **嵌入式 WebView 登录页面展示** 当目标平台不具备原生渲染能力或者想要保持一致性的视觉风格时,考虑采用 iframe 方式加载远程 HTML 内容不失为一种折衷办法。不过需要注意的是这种方式可能会带来一定的安全隐患因此务必谨慎评估风险后再决定是否采纳[^2]。 4. **支持多种协议适配不同场景下的需求** 不同的企业客户往往有着各自偏爱的技术栈组合所以有必要提前确认清楚对方所期望遵循的标准是什么然后再据此调整我们的解决方案设计思路。目前 Casdoor 至少已经实现了对于 OpenID Connect, Security Assertion Markup Language(SAML), Lightweight Directory Access Protocol(LDAP)等多种流行规格的支持从而极大地拓宽了适用范围[^3]。 ```python import requests def authenticate_user(username, password): url = 'http://your_casdoor_instance/api/login' payload = { 'username': username, 'password': password } response = requests.post(url, json=payload) if response.status_code == 200: token_data = response.json() return f"Token received successfully! {token_data}" else: error_message = response.text raise Exception(f"Authentication failed with message: {error_message}") ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值