Перейти до основного вмісту

RuoYi

Casdoor можна легко інтегрувати з RuoYi-cloud.

Крок 1: Розгортання Casdoor

Deploy Casdoor. See Server installation. Ensure the server is running (e.g. http://localhost:8000) and you can open the login page (e.g. http://localhost:7001) and sign in with admin / 123.

Крок 2: Налаштування Casdoor

Налаштуйте організацію, додаток та Синхронізатор у Casdoor. Notes:

  1. When editing the syncer, check the table columns: Table Columns.
  2. When editing the organization, select the correct password type: Password Type.
  3. Enable soft deletion.

Крок 3. Реформуйте ваш фронтенд

3.1 Перехід на сторінку входу Casdoor

Use a frontend SDK (e.g. vue-sdk). After initializing it, get the Casdoor login URL with getSigninUrl().

Wire the link as needed and remove any redundant RuoYi-Cloud login UI (e.g. account/password inputs).

3.2 Прийміть код і стан, повернуті Casdoor

Після успішного входу через Casdoor, Casdoor надсилає код і стан на сторінку, яку ми налаштували. Ми можемо отримати код і стан, використовуючи функцію create().

created() {
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 are not null, execute handleLogin
this.handleLogin();
}
}

Для RuoYi-Cloud ми просто змінюємо його оригінальний метод відправлення облікового запису та пароля на відправлення коду і стану замість цього. Отже, зміна полягає лише в тому, що відправляється на бекенд, у відношенні до оригінального входу.

Крок 4: Рефакторинг вашого бекенду

4.1 Прийміть код і стан, повернуті фронтендом

@PostMapping("login")
public R<?> callback(@RequestBody CodeBody code) {
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) {
sysLoginService.casdoorRegister(casdoorUserName); // Add this user to the database if they don't exist
}
}
LoginUser userInfo = sysLoginService.casdoorLogin(casdoorUser.getName()); // Get the user's information from the database
return R.ok(tokenService.createToken(userInfo));
}

У цьому методі ми використовуємо метод casdoor-SpringBoot-sdk і робимо невеликі зміни до методу RuoYi-Cloud.

Наприклад, оригінальний метод RuoYi-Cloud реєструє обліковий запис з паролем. Я змінив його на реєстрацію облікового запису за допомогою методу casdoorRegister.

Я також додав метод getUserByCasdoorName, щоб перевірити, чи існує обліковий запис, і змінив метод executeUserInfo на executeWithAccount, щоб відобразити цю зміну.

Це легка зміна, оскільки нам просто потрібно видалити частину, яка перевіряє пароль.

Крок 5: Підсумок

5.1 Фронтенд

  • Потрібно видалити існуючі сторінки входу та реєстрації.
  • Крім того, фронтенд повинен приймати параметри коду та стану та відправляти їх на бекенд.

5.2 Бекенд

Бекенд RuoYi вже має добре реалізовану функцію входу та реєстрації. Нам просто потрібно зробити деякі невеликі зміни, що робить процес надзвичайно зручним.

Крок 6: Детальні кроки

  1. Розгорніть та налаштуйте Casdoor. Обов'язково оберіть тип пароля bcrypt для організації, оскільки RuoYi-Cloud також використовує bcrypt для паролів.

  2. Використовуйте синхронізатори Casdoor для копіювання користувачів бази даних у вашу організацію Casdoor. Це імпортує оригінальні облікові записи до Casdoor.

  3. Після розгортання Casdoor, зробіть зміни у фронтенді. Вимкніть перевірку коду RuoYi.

    перемикач checkcode

    Зверніть увагу, що капчу RuoYi-Cloud потрібно знову вимкнути в Nacos. Також функцію реєстрації RuoYi-Cloud потрібно включити, встановивши sys.account.registerUser у true.

  4. Додайте кнопку для входу користувачів через Casdoor і змініть дані loginForm.

    кнопка увійти дані loginForm The URL can also be obtained from Casdoor-Vue-SDK or Casdoor-SpringBoot-SDK.

  5. Оскільки ми більше не використовуємо оригінальний метод входу, видаліть методи cookie та checkcode.

    Нова функція created повинна виглядати так:

    created() {
    let url = window.document.location.href; // Get the URL
    let u = new URL(url);
    this.loginForm.code = u.searchParams.get('code'); // Get the code and state
    this.loginForm.state = u.searchParams.get('state');
    if (this.loginForm.code != null && this.loginForm.state != null) { // If code and state are not null, execute handleLogin
    this.handleLogin();
    }
    }
  6. Насправді, нам потрібно лише змінити параметр, який ми відправляємо на бекенд, і видалити непотрібні функції. Інших змін не потрібно.

    handleLogin Увійти увійти

  7. Імпортуйте необхідну залежність у бекенд.

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

    Вам також потрібно налаштувати Casdoor у файлі ресурсів.

  8. Визначте функцію зворотного виклику як функцію перенаправлення. Зробіть зміни до деяких методів у sysLoginService. Видаліть крок перевірки пароля, оскільки він більше не потрібен.

    @PostMapping("login")
    public R<?> callback(@RequestBody CodeBody code) {
    // Define a CodeBody entity with 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 the user is not in the RuoYi-Cloud database but exists in Casdoor, create the user in the database
    sysLoginService.casdoorRegister(casdoorUserName);
    }
    }
    LoginUser userInfo = sysLoginService.casdoorLogin(casdoorUser.getName());
    // Get the user's information from the database
    return R.ok(tokenService.createToken(userInfo));
    }
  9. Додайте нові методи до SysLoginService.

    public LoginUser casdoorLogin(String username) {
    R<LoginUser> userResult = remoteUserService.getUserInfo(username, SecurityConstants.INNER);
    // Execute the user
    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 does not exist");
    throw new ServiceException("User " + username + " does 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 has been deleted");
    throw new ServiceException("Sorry, your account " + username + " has been deleted");
    }
    if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
    recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "Your account is disabled. Please contact the administrator");
    throw new ServiceException("Sorry, your account " + username + " is disabled");
    }
    recordLogService.recordLogininfor(username, Constants.LOGIN_SUCCESS, "Login successful");
    return userInfo;
    }
    public String getUserByCasdoorName(String casdoorUsername) {
    R<LoginUser> userResult = remoteUserService.getUserInfo(casdoorUsername, SecurityConstants.INNER);
    if (StringUtils.isNull(userResult) || StringUtils.isNull(userResult.getData())) {
    // If the user is not in the RuoYi-Cloud database but exists in Casdoor, create the user in the 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 provide a username");
    }
    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, "Registration successful");
    }