RuoYi
Casdoor может быть легко интегрирован с RuoYi-cloud.
Шаг 1: Развертывание Casdoor
Сначала разверните Casdoor.
Вы можете ознакомиться с официальной документацией Casdoor для установки сервера.
После успешного развертывания убедитесь в следующем:
- Сервер Casdoor работает по адресу http://localhost:8000.
- Откройте ваш любимый браузер и посетите http://localhost:7001, чтобы получить доступ к странице входа Casdoor.
- Протестируйте функционал входа, введя
admin
и123
.
Далее, вы можете быстро реализовать страницу входа на основе Casdoor в вашем собственном приложении, следуя этим шагам.
Шаг 2: Настройка Casdoor
Для настройки Casdoor, пожалуйста, следуйте этим шагам:
Откройте Casdoor в браузере, нажав здесь. Рекомендуется использовать другой браузер, чем ваш браузер для разработки.
Настройте организацию, приложение и Синхронизатор в Casdoor. Вы можете найти подробные инструкции о том, как это сделать здесь.
Вот некоторые дополнительные моменты, которые следует учитывать:
При редактировании синхронизатора убедитесь, что вы проверили столбцы таблицы: .
При редактировании организации убедитесь, что вы выбрали правильный тип пароля: .
Наконец, убедитесь, что вы включили мягкое удаление.
Пожалуйста, убедитесь, что вы внимательно следуете этим инструкциям для правильной настройки Casdoor.
Шаг 3. Реформируйте ваш фронтенд
3.1 Переход на страницу входа Casdoor
Мы можем использовать фронтенд SDK, в качестве примера здесь vue-sdk. После инициализации vue-sdk, вы можете получить URL страницы входа Casdoor, используя функцию getSigninUrl().
Вы можете связать его так, как предпочитаете, и не стесняйтесь удалять любой оригинальный код из Ruoyi-Cloud, который больше не нужен, такой как оригинальный аккаунт и пароль el-input.
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: Подробные шаги
Развернуть и настроить Casdoor. Обязательно выберите тип пароля bcrypt для организации, так как RuoYi-Cloud также использует bcrypt для паролей.
Используйте синхронизаторы Casdoor для копирования пользователей базы данных в вашу организацию Casdoor. Это позволит импортировать оригинальные аккаунты в Casdoor.
После развертывания Casdoor внесите изменения в фронтенд. Отключите проверку кода RuoYi.
Обратите внимание, что капчу RuoYi-Cloud нужно снова отключить в Nacos. Также функцию регистрации RuoYi-Cloud нужно включить, установив
sys.account.registerUser
вtrue
.Добавьте кнопку для входа пользователей через Casdoor и измените данные
loginForm
.Здесь я написал URL, но вы можете получить его, используя Casdoor-Vue-SDK или Casdoor-SpringBoot-SDK.
Поскольку мы больше не используем оригинальный метод входа, удалите методы 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();
}
}На самом деле, нам нужно только изменить параметр, который мы отправляем на бэкенд, и удалить ненужные функции. Другие изменения не требуются.
Импортируйте необходимую зависимость в бэкенд.
pom.xml<dependency>
<groupId>org.casbin</groupId>
<artifactId>casdoor-spring-boot-starter</artifactId>
<version>1.2.0</version>
</dependency>Также вам нужно настроить Casdoor в ресурсном файле.
Определите функцию обратного вызова как функцию перенаправления. Внесите изменения в некоторые методы
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));
}Добавьте новые методы в
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");
}