Felhasználó regisztráció, adatok kezelése

Spring Boot + Spring Security + JPA + Thymeleaf + MySql

2021.06.22.

Röviden bemutatok egy Spring Boot alkalmazást, amely felhasználók és adataik kezelésére szolgál. Itt nem részletezek minden egyes fájlt, csak azokat amelyeket fontosnak tartok.

Az alkalmazás ismertetése:

Az alkalmazásban két szerepkört, USER és ADMIN használunk. Az ADMIN szerepkör jogosultságai: A USER szerpkör jogosultságai: Felhasználó adatai egy adatbázisban tároljuk, az alábbi séma szerint: A felhasználó regisztrál a weboldalunkon, a majd kap egy e-mail-t amely tartalmaz egy linket, a likre katintva véglegesíti a regisztrációját.
Regisztrálni csak USER szerepkörrel lehet. A bejelentkezés felhasználónév és jelszóval történik.

Alkalmazás elkészítéséhez használt komponensek:


Struktúra

project stucture

JPA entitások

@Entity annotációval látom el a User és Role osztályt. Az alkalmazás elidulásakor létrehozásra kerül három tábla: A users_roles tábla egy sora egy felhasználó és egy szerepkör egyedi azonosítójából áll. Kódrészlet az User.java fájlból:
          ...
          @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
          @JoinTable(name = "users_roles", joinColumns = {  @JoinColumn(name = "user_id") }, inverseJoinColumns = {
            @JoinColumn(name = "role_id") })
          private Set<Role> roles = new HashSet<Role>();
          ...

Státusz konstansok

A három státusz konstanst (A, P, D) a Status enumban példányosítom. A getDisplayValue() metódussal tudom lekérni a hozzájuk rendelt értékeket.
        public enum Status {

          A("Active"), P("Progress"), D("Deleted");

          private final String displayValue;

          private Status(String displayValue) {
            this.displayValue = displayValue;
          }

          public String getDisplayValue() {
            return displayValue;
          }
        }

Data.sql

A data.sql fájlban megadott alap adatokkal töltjük fel az adatbázisunk tábláit. INSERT INTO 'roles' (`id`, `role`) VALUES (1, 'ROLE_USER');
INSERT INTO 'roles' (`id`, `role`) VALUES (2, 'ROLE_ADMIN');

INSERT INTO 'users' (`id`, `first_name`, `last_name`, `username`, `date_of_birth`, `email`, `password`, `enabled`, `status`, `activation`) VALUES (1, 'Alfonz', 'Admin', 'admin', '1980-01-01', 'admin@test.com', '$2a$10$nDYm9EL00h/PzIFL1szXHul06U18hgUtgo7aRDS3ntYeSv7tiE4zO', b'1', 'A', 'CURRENT_TIMESTAMP');

INSERT INTO 'users_roles' (`user_id`, `role_id`) VALUES (1, 1), (1, 2);
A users táblában létrehozunk egy ADMIN jogosultsággal rendelkező felhasználót is.
Az ADMIN felhasználó felhasználóneve: admin
Az ADMIN felhasználó jelszava: admin

Konfiguráció

Az application.properties fájlban megadjuk az adatbázis eléréséhez szükséges adatokat. #MySql spring.datasource.url=jdbc:mysql://localhost:3306/adatbazis_neve spring.datasource.username=adatbazis_felhasznalonev spring.datasource.password=adatbazis_jelszo A JPA az entitánsok alapján létrehozza az adattáblákat és feltölti a data.sql-ben megadott tartalommal.
Mivel create-drop beállítással futtatom, így a szerver leállítása után töröl minden adatot amit a futtatás alatt létrehoztunk.
spring.jpa.hibernate.ddl-auto=create-drop A regisztrációs levél küldéséhez szintén az application.properties fájlban adjuk meg a levelezési postafiókunk adatait. Az itt megadott e-mail cím fog szerepelni a kiküldött levélben.
Létrehoztam egy base.url nevű változót amiben a szerver url-jét adom meg. Erre azért van szükség, hogy a regisztráció után működjön az aktiváló link a kiküldött levélben.

Main Controller

A MainController kezeli azon oldalakat amelyek jogosultság nélkül elérhetők.
A kontroller egyik feladata a regisztrációs űrlap megjelenítése, és a regisztrációs adatok továbbítása. Ha valótlan adat érkezik akkor visszakerülünk a regisztrációs oldalra, megjelenítve a hibát is. Sikeres regisztráció esetén a regisztrációs oldalon megjelenítünk egy "Sikeres regisztráció" üzenetet.
Kódrészlet a MainController.java fájlból:
          ...
          @PostMapping("/reg")
          public String regSubmit(@ModelAttribute("user") @Valid  UserRegistrationDto userRegDto, BindingResult result) {
            if  (result.hasErrors()) return "registration";
            userService.registerUser(userRegDto.convertToUser());
            return "redirect:/registration?success";
          }
          ...

SecurityConfig

A SecurityConfig.java fájlban beállítjuk, hogy mely reqest kéréseket engedélyezünk, valamint azok milyen szerepkörrel érhetőek el. Kódrészlet a SecurityConfig.java fájlból:
          ...
          @Override
          protected void configure(HttpSecurity http) throws Exception {
            http
              .authorizeRequests()
                .antMatchers("/users/**").hasRole("ADMIN")
                .antMatchers("/user/**").hasAnyRole("ADMIN", "USER")
                .antMatchers("/**/*.css",
                            "/",
                            "/home",
                            "/registration",
                            "/reg",
                            "/activation/**").permitAll()
                .anyRequest().authenticated().and()
                .formLogin()
                  .loginPage("/login")
                  .defaultSuccessUrl("/profile")
                  .permitAll().and()
                .logout()
                  .logoutSuccessUrl("/login?logout")
                  .permitAll();
          }
          ...

UserRegistrationDto

A UserRegistrationDto osztály végzi a regisztrációs adatok validálását. A validációkat annotációk segítségével hajtottam végre.
Saját annotációk:
A resources mappában a hibaüzenetek megjelenítésére létrehoztam egy messages_en.properties és egy messages_hu.properties fájlt.

Regisztráció

A regisztráció a bejelenkezési oldalról érhető el. A regisztációnak nem készítettem külön menüpontot, mert minden felhasználó többnyire egyszer kattint rá. regisztracios form Az általam megadott regisztrációs adatok: Sikeres regisztráció esetén egy üzenetet kapunk, valamint a megadott e-mail címre egy regisztrációs levelet. email megerkezett A levél tartalma: email szövege

User szerepkör

user menü
Profil menüpont
Bejelentezés után a profil oldal jelenik meg: profil oldal
Profil szerkesztése menüpont
Itt a felhasználó szerkeszheti a saját adatait.
Az adatokat validálás után lehet módosítani, egyébként hibaüzenetet kapunk. Például ha a felhasználó olyan e-mail címet szeretne megadni ami már szerpel az adatbázisban akkor hibaüzenetet kap.
Az adatok módosításához jelszó is szükséges!
profil szerkesztése oldal
Jelszó módosítás menüpont
Ebben a menüpontban a felhasználó lecserélheti a jelszavát.
A régi és az új jelszó nem egyezhet meg, valamint az új jelszónak a regisztráció során elvárt kritériumoknak meg kell felelnie.
jelszó módosítása oldal
Profil törlése menüpont
A felhasználó jelszava megadását követően kérheti profilja törlését.
A profil logikai törlését ADMIN jogosultsággal rendelkező felhasználó tudja végrehajtani.
jelszó módosítása oldal

Admin szerepkör

A bejelenkezési oldalon az admin/admin párossal be tudunk jelentezni ADMIN jogosultsággal. admin menü
Felhasználók menüpont
ADMIN felhasználók megtekinthetik a felhasználó adatait a gombbal.
Felhasználónak ADMIN jogosultság adása a Add Role gombbal történik.
Az aktív státusszal rendelkező felhasználóknál jelenik meg, ahol a felhasználó státusza (törlésre vár) ott a gombra kattintva a felhasználó státusza D (törölt) lesz.
felhasználók oldal

Köszönöm ha végigolvastad!

Amennyiben kérdésed lenne, keress elérhetőségeim egyikén!
Github: spring-boot-jpa-thymeleaf-mysql
A következő projektemben frontend oldalon Thymeleaf helyett Vue.CLI-t használok.