简体中文 / [English]


Building a Chat App with Spring Boot + React Ep.1 - Backend Database Setup and User Login/Registration

 

This article is currently an experimental machine translation and may contain errors. If anything is unclear, please refer to the original Chinese version. I am continuously working to improve the translation.

This series documents my journey learning Spring + React from scratch while building a small project, sharing experiences and insights along the way. It's for reference only and not intended as a formal tutorial. For project overview, see Ep.0.

First things first — we need to implement user-related functionalities like registration, login, logout, and password modification.

Spring Project Layering

It’s pretty much the standard layered architecture — Controller handles requests, Service provides business logic, DAO (or Mapper) deals with data persistence, and Entity represents domain objects.

Corresponding Java packages were created in the project to organize these components.

Database Configuration

Spin up a MySQL + Redis database, add Gradle dependencies, and configure them in the config files — that’s it!

Originally I planned to create db/schema.sql under resources and write SQL statements for table creation.
Also intended to add the following code in application.yaml to enable automatic conversion between camelCase and snake_case naming in MyBatis mappings.

Initially tried using MyBatis, but found it not “automated” enough — too much reliance on code generators or manual tweaks. The root cause? It doesn’t offer full ORM capabilities; entity classes can’t be perfectly mapped to database schemas.

So I switched to JPA (Hibernate). Now, by simply writing clean Java code, tables are created automatically and basic CRUD operations are handled out of the box. Much cleaner and more elegant in my opinion.

https://www.baeldung.com/spring-boot-hibernate

API Design

Went with a RESTful API design.

https://www.ruanyifeng.com/blog/2014/05/restful_api.html

Immediately hit decision paralysis… Spent way too long figuring out how to design login RESTfully.

Ideally, REST is stateless and shouldn’t manage sessions. But without alternative authentication methods, I had to make some compromises…

Referenced this discussion: https://stackoverflow.com/questions/7140074/restfully-design-login-or-register-resources

  • GET /session/new gets the webpage that has the login form
  • POST /session authenticates credentials against database
  • DELETE /session destroys session and redirects to /
  • GET /users/new gets the webpage that has the registration form
  • POST /users records the entered information into database as a new /user/xxx
  • GET /users/xxx // gets and renders current user data in a profile view
  • POST /users/xxx // updates new information about user

API responses should use snake_case in JSON. Added the following to application.yaml to enforce this, while also excluding null-valued properties from responses:

1
2
3
4
5
spring:
jackson:
# snake case style for response json
property-naming-strategy: SNAKE_CASE
default-property-inclusion: non_null

Swagger

Using Swagger to automatically generate API documentation. Tools like Apifox can import Swagger specs with one click, saving tons of time on manual doc maintenance.

Choosing an Authentication Framework

Initially planned to write a custom Interceptor to handle request filtering. But after some research, I discovered dedicated authentication frameworks — the old-school ones like Apache Shiro or Spring Security.

Ended up spending several hours digging through Spring Security and Shiro documentation. Man, it’s so complicated…

Then I came across Sa-Token, the new kid on the block: https://github.com/dromara/sa-token
It’s much more suitable for modern frontend-backend separated applications and way simpler to use. Spring Security and Shiro feel a bit outdated and over-engineered — you’d have to tweak a lot just to make them work smoothly in a SPA context.

1
2
3
4
5
6
7
// Clean and elegant authentication!
// During login, write the current session's user ID
StpUtil.login(10001);

// Then, wherever login validation is needed:
// This line throws a `NotLoginException` if the session isn't logged in
StpUtil.checkLogin();

Bonus: Sa-Token also includes built-in support for BCrypt — perfect for securely hashing passwords with salt.

This article is licensed under the CC BY-NC-SA 4.0 license.

Author: lyc8503, Article link: https://blog.lyc8503.net/en/post/my-chat-1-backend-authorization/
If this article was helpful or interesting to you, consider buy me a coffee¬_¬
Feel free to comment in English below o/