Passer au contenu principal

RuoYi

Casdoor peut être facilement intégré avec RuoYi-cloud.

Étape 1 : Déployer 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.

Étape 2 : Configurer Casdoor

Configurez une organisation, une application et le Synchroniseur dans 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.

Étape 3. Réformez votre front-end

3.1 Aller à la page de connexion de 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 Accepter le code et l'état renvoyés par Casdoor

Après une connexion réussie via Casdoor, Casdoor envoie le code et l'état à la page que nous avons configurée. Nous pouvons récupérer le code et l'état en utilisant la fonction 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();
}
}

Pour RuoYi-Cloud, nous modifions simplement sa méthode originale d'envoi du compte et du mot de passe pour envoyer le code et l'état à la place. Par conséquent, le changement concerne uniquement ce qui est envoyé au backend, par rapport à la connexion originale.

Étape 4 : Refactorisez votre back-end

4.1 Accepter le code et l'état renvoyés par le 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));
}

Dans cette méthode, nous utilisons la méthode casdoor-SpringBoot-sdk et apportons de légères modifications à la méthode RuoYi-Cloud.

Par exemple, la méthode originale de RuoYi-Cloud enregistre un compte avec un mot de passe. Je l'ai changée pour enregistrer un compte en utilisant la méthode casdoorRegister.

J'ai également ajouté une méthode getUserByCasdoorName pour vérifier si le compte existe, et changé la méthode executeUserInfo en executeWithAccount pour refléter ce changement.

C'est une modification facile, car nous avons seulement besoin de supprimer la partie qui vérifie le mot de passe.

Étape 5 : Résumé

5.1 Front-end

  • Les pages de connexion et d'inscription existantes doivent être supprimées.
  • De plus, le front-end doit accepter les paramètres de code et d'état et les envoyer au back-end.

5.2 Back-end

Le back-end de RuoYi dispose déjà d'une fonction de connexion et d'inscription bien implémentée. Nous avons juste besoin d'apporter quelques modifications mineures, ce qui rend le processus très pratique.

Étape 6 : Étapes détaillées

  1. Déployez et configurez Casdoor. Assurez-vous de sélectionner le type de mot de passe bcrypt pour l'organisation, car RuoYi-Cloud utilise également bcrypt pour les mots de passe.

  2. Utilisez les synchroniseurs Casdoor pour copier les utilisateurs de la base de données dans votre organisation Casdoor. Cela importera les comptes originaux dans Casdoor.

  3. Après avoir déployé Casdoor, apportez des modifications au front-end. Désactivez le code de vérification RuoYi.

    Interrupteur de code de vérification

    Notez que le captcha RuoYi-Cloud doit être désactivé dans Nacos à nouveau. De plus, la fonction d'inscription RuoYi-Cloud doit être activée en définissant sys.account.registerUser sur true.

  4. Ajoutez un bouton pour que les utilisateurs se connectent avec Casdoor, et modifiez les données du loginForm.

    bouton de connexion données formulaireDeConnexion The URL can also be obtained from Casdoor-Vue-SDK or Casdoor-SpringBoot-SDK.

  5. Comme nous n'utilisons plus la méthode de connexion originale, supprimez les méthodes cookie et checkcode.

    La nouvelle fonction created devrait ressembler à ceci :

    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. En fait, nous avons seulement besoin de changer le paramètre que nous envoyons au back-end et de supprimer les fonctions inutiles. Aucun autre changement n'est nécessaire.

    gérerConnexion Connexion connexion

  7. Importez la dépendance requise dans le back-end.

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

    Vous devez également configurer Casdoor dans le fichier de ressources.

  8. Définissez la fonction de rappel comme la fonction de redirection. Apportez des modifications à certaines méthodes dans sysLoginService. Supprimez l'étape de vérification du mot de passe car elle n'est plus nécessaire.

    @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. Ajoutez de nouvelles méthodes à 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");
    }