RuoYi
O Casdoor pode ser facilmente integrado com o RuoYi-cloud.
Passo 1: Implementar o Casdoor
Primeiro, implemente o Casdoor.
Você pode consultar a documentação oficial do Casdoor para a Instalação do Servidor.
Após a implementação bem-sucedida, certifique-se do seguinte:
- O servidor Casdoor está em execução em http://localhost:8000.
- Abra seu navegador favorito e visite http://localhost:7001 para acessar a página de login do Casdoor.
- Teste a funcionalidade de login inserindo
admin
e123
.
Em seguida, você pode implementar rapidamente uma página de login baseada no Casdoor em seu próprio aplicativo seguindo estes passos.
Passo 2: Configurar o Casdoor
Para configurar o Casdoor, siga estes passos:
Abra o Casdoor em um navegador clicando aqui. É recomendado usar um navegador diferente do seu navegador de desenvolvimento.
Configure uma organização, uma aplicação e o Sincronizador no Casdoor. Você pode encontrar instruções detalhadas sobre como fazer isso aqui.
Aqui estão alguns pontos adicionais a ter em mente:
Ao editar o sincronizador, certifique-se de verificar as colunas da tabela: .
Ao editar a organização, certifique-se de selecionar o tipo de senha correto: .
Por último, certifique-se de que você habilitou a exclusão suave.
Por favor, certifique-se de seguir estas instruções cuidadosamente para configurar o Casdoor corretamente.
Passo 3. Reforme seu front-end
3.1 Ir para a página de login do Casdoor
Podemos usar um SDK de front-end, tomando vue-sdk como exemplo aqui. Depois de inicializar o vue-sdk, você pode obter a URL da página de login do Casdoor usando a função getSigninUrl().
Você pode vinculá-la da maneira que preferir e sinta-se à vontade para deletar qualquer código original do Ruoyi-Cloud que não seja mais necessário, como a entrada original de conta e senha el-input.
3.2 Aceitar o código e o estado retornados pelo Casdoor
Após fazer login com sucesso através do Casdoor, o Casdoor envia o código e o estado para a página que configuramos. Podemos recuperar o código e o estado usando a função 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();
}
}
Para o RuoYi-Cloud, simplesmente modificamos seu método original de enviar a conta e a senha para enviar o código e o estado em vez disso. Portanto, a mudança é apenas no que é enviado ao back-end, em relação ao login original.
Passo 4: Refatorar seu back-end
4.1 Aceitar o código e o estado retornados pelo front-end
@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));
}
Neste método, estamos usando o método casdoor-SpringBoot-sdk e fazendo pequenas modificações no método RuoYi-Cloud.
Por exemplo, o método original do RuoYi-Cloud registra uma conta com uma senha. Eu mudei para registrar uma conta usando o método casdoorRegister
.
Também adicionei um método getUserByCasdoorName
para verificar se a conta existe e mudei o método executeUserInfo
para executeWithAccount
para refletir essa mudança.
Esta é uma modificação fácil, pois só precisamos remover a parte que verifica a senha.
Passo 5: Resumo
5.1 Front-end
- As páginas de login e registro existentes precisam ser removidas.
- Além disso, o front-end precisa aceitar parâmetros de código e estado e enviá-los para o back-end.
5.2 Back-end
O back-end do RuoYi já possui uma função de login e registro bem implementada. Só precisamos fazer algumas modificações menores, o que torna o processo altamente conveniente.
Passo 6: Passos Detalhados
Implementar e configurar o Casdoor. Certifique-se de selecionar o tipo de senha bcrypt para a organização, pois o RuoYi-Cloud também usa bcrypt para senhas.
Use os sincronizadores do Casdoor para copiar usuários do banco de dados para a sua organização Casdoor. Isso importará as contas originais para o Casdoor.
Após implementar o Casdoor, faça alterações no front-end. Desative o código de verificação do RuoYi.
Observe que o captcha do RuoYi-Cloud precisa ser desativado no Nacos novamente. Além disso, a função de registro do RuoYi-Cloud precisa ser habilitada definindo
sys.account.registerUser
paratrue
.Adicione um botão para os usuários fazerem login com o Casdoor e modifique os dados do
loginForm
.Aqui, eu escrevi a URL, mas você pode obtê-la usando o Casdoor-Vue-SDK ou Casdoor-SpringBoot-SDK.
Como não estamos mais usando o método de login original, delete os métodos de cookie e código de verificação.
A nova função
created
deve parecer assim: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();
}
}Na verdade, só precisamos mudar o parâmetro que enviamos para o back-end e deletar as funções desnecessárias. Nenhuma outra mudança é necessária.
Importe a dependência necessária no back-end.
pom.xml<dependency>
<groupId>org.casbin</groupId>
<artifactId>casdoor-spring-boot-starter</artifactId>
<version>1.2.0</version>
</dependency>Você também precisa configurar o Casdoor no arquivo de recursos.
Defina a função de retorno como a função de redirecionamento. Faça alterações em alguns métodos em
sysLoginService
. Delete a etapa de verificação de senha, pois ela não é mais necessária.@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));
}Adicione novos métodos ao
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");
}