Search

๋กœ๊ทธ์ธ ์•ฑ

๋กœ๊ทธ์ธ ์•ฑ

์ด๋ฒˆ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” Flutter(ํ”Œ๋Ÿฌํ„ฐ)์™€ Spring Boot(์Šคํ”„๋ง ๋ถ€ํŠธ)๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ์ด ํฌํ•จ๋œ ์•ฑ์„ ๋งŒ๋“ค์–ด๋ณผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ํ”„๋กœ์ ํŠธ ๊ฐœ์š”

โ€ข
Frontend: Flutter๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ชจ๋ฐ”์ผ ์•ฑ UI๋ฅผ ๊ฐœ๋ฐœํ•ฉ๋‹ˆ๋‹ค.
โ€ข
Backend: Spring Boot๋ฅผ ์ด์šฉํ•˜์—ฌ ํšŒ์›๊ฐ€์ž…, ๋กœ๊ทธ์ธ, JWT ์ธ์ฆ ๋“ฑ ์„œ๋ฒ„ ๊ธฐ๋Šฅ์„ ๊ตฌ์ถ•ํ•ฉ๋‹ˆ๋‹ค.
โ€ข
Database: MySQL ๋˜๋Š” PostgreSQL์„ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

์ฃผ์š” ๊ธฐ๋Šฅ

ํšŒ์›๊ฐ€์ž… โ€“ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ์ž…๋ ฅ๋ฐ›์•„ ๊ณ„์ •์„ ์ƒ์„ฑ
๋กœ๊ทธ์ธ โ€“ ID/PW ์ธ์ฆ ๋ฐ JWT(ํ† ํฐ) ๋ฐฉ์‹ ๋กœ๊ทธ์ธ
์ž๋™ ๋กœ๊ทธ์ธ โ€“ Secure Storage๋ฅผ ํ™œ์šฉํ•œ ๋กœ๊ทธ์ธ ์œ ์ง€
๋กœ๊ทธ์•„์›ƒ โ€“ ํ† ํฐ ์‚ญ์ œ ๋ฐ ์ธ์ฆ ํ•ด์ œ

Github

Flutter

FLUTTER_JWT_LOGIN
ALOHA-CLASS

Spring Boot

ํ”Œ๋Ÿฌํ„ฐ ์•ฑ ๊ฐœ๋ฐœ ์ˆœ์„œ

1.
ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ
2.
ํ”„๋กœ์ ํŠธ ์„ค์ •
3.
ํ™”๋ฉด UI ๊ฐœ๋ฐœ
โ€ข
ํ™ˆ
โ€ข
ํšŒ์›๊ฐ€์ž…
โ€ข
๋กœ๊ทธ์ธ
โ€ข
๋งˆ์ดํŽ˜์ด์ง€
4.
๊ธฐ๋Šฅ ๊ฐœ๋ฐœ
a.
ํšŒ์›๊ฐ€์ž…
b.
๋กœ๊ทธ์ธ
c.
๋กœ๊ทธ์•„์›ƒ
d.
ํšŒ์›์ •๋ณด ์ˆ˜์ •
e.
ํšŒ์› ํƒˆํ‡ด

ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ

ํ”„๋กœ์ ํŠธ ์„ค์ •

โ€ข
์˜์กด์„ฑ ํŒจํ‚ค์ง€ ์„ค์ •
โ€ข
์•ˆ๋“œ๋กœ์ด๋“œ ์„ค์ •

์˜์กด์„ฑ ํŒจํ‚ค์ง€ ์„ค์ •

pubspec.yaml

name: login_app description: "A new Flutter project." publish_to: 'none' version: 1.0.0+1 environment: sdk: ^3.6.1 dependencies: flutter: sdk: flutter cupertino_icons: ^1.0.8 # ์ถ”๊ฐ€ํ•œ ํŒจํ‚ค์ง€ dio: ^5.8.0+1 flutter_secure_storage: ^9.2.4 shared_preferences: ^2.5.1 provider: ^6.1.2 dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^5.0.0 flutter: uses-material-design: true
YAML
๋ณต์‚ฌ

์•ˆ๋“œ๋กœ์ด๋“œ ์„ค์ •

โ€ข
android/gradle.properties
โ€ข
android/app/build.gradle

android/gradle.properties

org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError android.useAndroidX=true android.enableJetifier=true org.gradle.java.home=C:/Program Files/Java/jdk-17
Java
๋ณต์‚ฌ

android/app/build.gradle

plugins { id "com.android.application" id "kotlin-android" id "dev.flutter.flutter-gradle-plugin" } android { namespace = "com.example.login_app" compileSdk = flutter.compileSdkVersion ndkVersion = flutter.ndkVersion compileOptions { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { jvmTarget = JavaVersion.VERSION_17 } defaultConfig { applicationId = "com.example.login_app" minSdk = flutter.minSdkVersion targetSdk = flutter.targetSdkVersion versionCode = flutter.versionCode versionName = flutter.versionName } buildTypes { release { signingConfig = signingConfigs.debug } } } flutter { source = "../.." }
Java
๋ณต์‚ฌ

ํ™”๋ฉด UI ๊ฐœ๋ฐœ

โ€ข
ํ™ˆ
โ€ข
ํšŒ์›๊ฐ€์ž…
โ€ข
๋กœ๊ทธ์ธ
โ€ข
๋กœ๊ทธ์•„์›ƒ
โ€ข
๋งˆ์ดํŽ˜์ด์ง€

๋กœ๊ณ  ์ด๋ฏธ์ง€

logo.png
292.5KB

ํ™ˆ

ํšŒ์›๊ฐ€์ž…

๋กœ๊ทธ์ธ

๋กœ๊ทธ์•„์›ƒ

๋งˆ์ดํŽ˜์ด์ง€

๊ธฐ๋Šฅ ๊ฐœ๋ฐœ

1.
ํšŒ์›๊ฐ€์ž…
2.
๋กœ๊ทธ์ธ
a.
์•„์ด๋”” ์ €์žฅ
b.
์ž๋™ ๋กœ๊ทธ์ธ
3.
๋กœ๊ทธ์•„์›ƒ
4.
ํšŒ์›์ •๋ณด ์ˆ˜์ •
5.
ํšŒ์› ํƒˆํ‡ด

ํšŒ์›๊ฐ€์ž…

ํšŒ์›๊ฐ€์ž… ์ •๋ณด(์•„์ด๋””, ๋น„๋ฐ€๋ฒˆํ˜ธ, ์ด๋ฆ„, ์ด๋ฉ”์ผ)๋ฅผ ์ž…๋ ฅํ•˜๊ณ , ์„œ๋ฒ„ ์ธก์— ํšŒ์› ์ •๋ณด๊ฐ€ ๋“ฑ๋ก ๋˜๋„๋ก ์š”์ฒญํ•˜๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.
ํ•ญ๋ชฉ
๋‚ด์šฉ
์š”์ฒญ URL
์š”์ฒญ ๋ฉ”์†Œ๋“œ
POST
์š”์ฒญ ๋ณธ๋ฌธ (body)
{ โ€œusernameโ€ : โ€œalohaโ€, โ€œpasswordโ€ : โ€œ123456โ€, โ€œnameโ€ : โ€œ์•Œ๋กœํ•˜โ€, โ€œemailโ€ : โ€œaloha@aloha.comโ€ }
์ƒํƒœ ์ฝ”๋“œ ์„ฑ๊ณต
200
์ƒํƒœ ์ฝ”๋“œ ์‹คํŒจ
400

๋กœ๊ทธ์ธ

์•„์ด๋””์™€ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•˜์—ฌ ์„œ๋ฒ„๋กœ ์š”์ฒญํ•˜์—ฌ ์ธ์ฆ๋ฐ›๊ณ , JWT์™€ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ์‘๋‹ต๋ฐ›๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.

๊ด€๋ จ ๊ธฐ๋Šฅ

โ€ข
์•„์ด๋”” ์ €์žฅ
โ€ข
์ž๋™ ๋กœ๊ทธ์ธ
ํ•ญ๋ชฉ
๋‚ด์šฉ
์š”์ฒญ URL
์š”์ฒญ ๋ฉ”์†Œ๋“œ
POST
์š”์ฒญ ๋ณธ๋ฌธ (body)
{ โ€œusernameโ€ : โ€œalohaโ€, โ€œpasswordโ€ : โ€œ123456โ€, }
์ƒํƒœ ์ฝ”๋“œ ์„ฑ๊ณต
200
์ƒํƒœ ์ฝ”๋“œ ์‹คํŒจ
401

์•„์ด๋”” ์ €์žฅ

์•„์ด๋”” ์ €์žฅ ์ฒดํฌ ํ›„ ๋กœ๊ทธ์ธ ์‹œ๋„ํ•œ ์•„์ด๋””๋ฅผ, ๋กœ๊ทธ์ธ ํ™”๋ฉด์ด ๋‹ค์‹œ ์—ด๋ ธ์„ ๋•Œ, ์ €์žฅ๋œ ์•„์ด๋””๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ๊ธฐ๋Šฅ
1.
์•„์ด๋”” ์ €์žฅ ์ฒดํฌ ๋ฐ•์Šค ์ฒดํฌ ์‹œ, SecureStorage ์— ์•„์ด๋”” ์ €์žฅ
2.
๋กœ๊ทธ์ธ ํ™”๋ฉด์—์„œ SecureStorage ์ €์žฅ๋œ ์•„์ด๋””๊ฐ€ ์žˆ์œผ๋ฉด ์•„์ด๋”” ์ž…๋ ฅ์— ์ถœ๋ ฅ

์ž๋™ ๋กœ๊ทธ์ธ

์ž๋™ ๋กœ๊ทธ์ธ ์ฒดํฌ ํ›„ ๋กœ๊ทธ์ธ ์‹œ๋„ํ•œ ์•„์ด๋””๋ฅผ, ์ €์žฅ๋œ JWT ํ† ํฐ์„ ์ด์šฉํ•ด์„œ, ์„œ๋ฒ„์— ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ์š”์ฒญํ•˜๊ณ  ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๋Š” ๊ธฐ๋Šฅ
1.
์ž๋™ ๋กœ๊ทธ์ธ ์ฒดํฌ ์‹œ,
a.
SecureStorage ์— JWT ์ €์žฅ
b.
์ž๋™ ๋กœ๊ทธ์ธ ์—ฌ๋ถ€ ์ €์žฅ
2.
์•ฑ ์žฌ์‹คํ–‰ ์‹œ, SecureStorage ์ €์žฅ๋œ JWT ๋กœ ์„œ๋ฒ„์— ์‚ฌ์šฉ์ž ์ •๋ณด ์š”์ฒญ
3.
์‘๋‹ต ๋ฐ›์€ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ Provider ์— ๋“ฑ๋ก

๋กœ๊ทธ์•„์›ƒ

๋กœ๊ทธ์ธ ์ƒํƒœ์—์„œ ๋กœ๊ทธ์•„์›ƒ์„ ์š”์ฒญํ•˜๋ฉด ๋กœ์ปฌ ์ €์žฅ์†Œ์— ์ €์žฅ๋œ JWT์™€ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ์‚ญ์ œํ•˜์—ฌ ๋กœ๊ทธ์•„์›ƒ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.
JWT ํ† ํฐ ์‚ญ์ œ
Provider ์‚ฌ์šฉ์ž ์ •๋ณด ์ดˆ๊ธฐํ™”
Provider ๋กœ๊ทธ์ธ ์ƒํƒœ ์ดˆ๊ธฐํ™”

ํšŒ์›์ •๋ณด ์ˆ˜์ •

๋กœ๊ทธ์ธํ•œ ์‚ฌ์šฉ์ž์˜ ํšŒ์› ์ •๋ณด(์ด๋ฆ„, ์ด๋ฉ”์ผ)๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ์ˆ˜์ •๋œ ์ •๋ณด๋Š” ์„œ๋ฒ„์— ๋ฐ˜์˜๋ฉ๋‹ˆ๋‹ค.
ํ•ญ๋ชฉ
๋‚ด์šฉ
์š”์ฒญ URL
์š”์ฒญ ๋ฉ”์†Œ๋“œ
PUT
์š”์ฒญ ํ—ค๋”
Authorization: Bearer {JWT ํ† ํฐ}
์š”์ฒญ ๋ณธ๋ฌธ (body)
{ โ€œusernameโ€: โ€œuserโ€, "name" : "์•Œ๋กœํ•˜2", "email" : "aloha2@aloha.com" }
์ƒํƒœ ์ฝ”๋“œ ์„ฑ๊ณต
200
์ƒํƒœ ์ฝ”๋“œ ์‹คํŒจ
401, 403

ํšŒ์› ํƒˆํ‡ด

๋กœ๊ทธ์ธํ•œ ์‚ฌ์šฉ์ž์˜ ํšŒ์› ์ •๋ณด๋ฅผ ์‚ญ์ œํ•˜๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ํšŒ์› ํƒˆํ‡ด ์‹œ ํ•ด๋‹น ์‚ฌ์šฉ์ž์˜ ๋ชจ๋“  ์ •๋ณด๊ฐ€ ์„œ๋ฒ„์—์„œ ์‚ญ์ œ๋ฉ๋‹ˆ๋‹ค.
ํ•ญ๋ชฉ
๋‚ด์šฉ
์š”์ฒญ URL
์š”์ฒญ ๋ฉ”์†Œ๋“œ
DELETE
์š”์ฒญ ํ—ค๋”
Authorization:Bearer {JWT ํ† ํฐ}
์ƒํƒœ ์ฝ”๋“œ ์„ฑ๊ณต
200
์ƒํƒœ ์ฝ”๋“œ ์‹คํŒจ
401, 403