์นด์นด์ค ๋ก๊ทธ์ธ
1.
์นด์นด์ค ๋ก๊ทธ์ธ ์๊ฐ
a.
์นด์นด์ค ๋ก๊ทธ์ธ ํน์ง
b.
์นด์นด์ค ์ ๊ณต ๊ธฐ๋ฅ
c.
์นด์นด์ค ๋ก๊ทธ์ธ - Kakao developers
i.
Kakao Developers ์นด์นด์ค ๋ก๊ทธ์ธ
2.
์นด์นด์ค ๋ก๊ทธ์ธ ์์ํ๊ธฐ
b.
์์ํ๊ธฐ
c.
์ ํ๋ฆฌ์ผ์ด์
์ถ๊ฐํ๊ธฐ
3.
์นด์นด์ค ์ ํ๋ฆฌ์ผ์ด์
์ค์ ํ๊ธฐ
a.
์ฑ ์ค์
i.
์ฑ ํค
1.
REST API ํค ๋ณต์ฌ
ii.
ํ๋ซํผ
1.
์ฌ์ดํธ ๋๋ฉ์ธ ๋ฑ๋ก
b.
์ ํ ์ค์
i.
์นด์นด์ค ๋ก๊ทธ์ธ
1.
ํ์ฑํ ์ค์ ON
2.
Redirect URI ๋ฑ๋ก
ii.
๋์ ํญ๋ชฉ
1.
๋๋ค์
2.
ํ๋กํ ์ฌ์ง
3.
์นด์นด์ค ๊ณ์ (์ด๋ฉ์ผ)
c.
๋ณด์
i.
Client Secret ํค ๋ฐ๊ธ
4.
Spring Security x OAuth x ์นด์นด์ค ์ฐ๋ํ๊ธฐ
a.
ํ๋ก์ ํธ ์์ฑ
b.
์์กด์ฑ ์ถ๊ฐ
i.
์ฃผ์ ์์กด์ฑ
1.
Spring Security
2.
OAuth2 Client
ii.
๊ธฐ๋ณธ ์์กด์ฑ
1.
Spring Web
2.
SpringBoot Devtools
3.
Lombok
4.
Thymeleaf
5.
MySQL Driver
6.
MyBatis Framework
c.
ํ๋ก์ ํธ ์ค์
i.
properties profile ํ์ผ ์์ฑ
1.
application-oauth-kakao.properties
ii.
properties profile ํฌํจํ๊ธฐ(include)
1.
application.properties
d.
์คํ๋ง ์ํ๋ฆฌํฐ ์ค์
e.
์ปจํธ๋กค๋ฌ
i.
HomeController.java
f.
ํ๋ฉด
i.
index.html
ii.
login.html
์นด์นด์ค ๋ก๊ทธ์ธ ์๊ฐ
์นด์นด์ค ๋ก๊ทธ์ธ ํน์ง
์นด์นด์ค ๋ก๊ทธ์ธ์ ์นด์นด์ค ํ๋ซํผ์์ ์ ๊ณตํ๋ ํต์ฌ ๊ธฐ๋ฅ ์ค ํ๋์
๋๋ค. ์นด์นด์คํก ์ฌ์ฉ์๋ ์นด์นด์ค ๋ก๊ทธ์ธ์ ํตํด ์๋น์ค์ ์ฝ๊ณ ๋น ๋ฅด๊ฒ ๋ก๊ทธ์ธํ ์ ์๊ณ , ์ด๋ฅผ ํตํด ์ฌ๋ฌ๋ถ์ ๋ ๋ง์ ๊ณ ๊ฐ์ ํ๋ณดํ ์ ์์ต๋๋ค. ์นด์นด์ค ๋ก๊ทธ์ธ์ ๋์
ํ๋ฉด ์นด์นด์คํก์ ๋๋ค์๊ณผ ํ๋กํ ์ฌ์ง, ์ด๋ฉ์ผ, ์ฑ๋ณ, ์ฐ๋ น๋ ๋ฑ ์ฌ์ฉ์์ ๋์ ํ์ ์ป๋ ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ํ์ฉํ์ฌ ๊ฐ์ธํ๋ ์๋น์ค๋ฅผ ์ ๊ณตํ ์ ์์ต๋๋ค. ์ด๋ฏธ ์๋ง์ ์๋น์ค์์ ์นด์นด์ค ๋ก๊ทธ์ธ์ ๋์
ํ์ต๋๋ค. ์ ๋ขฐํ ์ ์๋ ์นด์นด์ค ๋ก๊ทธ์ธ์ ์ฌ์ฉํด ๋์ฑ ํธ๋ฆฌํ ์๋น์ค๋ฅผ ๋ง๋ค๊ณ ๋น์ฆ๋์ค์ ์ง์คํ์ธ์.
์นด์นด์ค ์ ๊ณต ๊ธฐ๋ฅ
โข
๋ก๊ทธ์ธ:ย ์นด์นด์ค๊ณ์ ์ ํตํ ๋น ๋ฅด๊ณ ๊ฐํธํ ์ฌ์ฉ์ ๋ก๊ทธ์ธ ๊ธฐ๋ฅ์
๋๋ค.
โข
๋ก๊ทธ์์:ย ์ฌ์ฉ์ ํ ํฐ์ ๋ง๋ฃ์์ผ ๋ก๊ทธ์ธ ์ํ๋ฅผ ํด์ ํฉ๋๋ค.
โข
์ฐ๊ฒฐ ๋๊ธฐ:ย ์นด์นด์ค ํ๋ซํผ์์ ์ฌ์ฉ์์ ์ฑ์ ์ฐ๊ฒฐ์ ํด์ ํฉ๋๋ค.
โข
ํ ํฐ ์ ๋ณด ๋ณด๊ธฐ:ย ์ก์ธ์ค ํ ํฐ(Access token)์ ์ ๋ณด์ ํ ํฐ์ ์ ํจ๊ธฐ๊ฐ์ ์ ๊ณตํฉ๋๋ค.
โข
์ฌ์ฉ์ ์ ๋ณด ๊ฐ์ ธ์ค๊ธฐ:ย ์ฌ์ฉ์ ์นด์นด์ค๊ณ์ ์ ๋ฑ๋ก๋ ์ ๋ณด๋ฅผ ์ ๊ณตํฉ๋๋ค.
โข
์ฌ์ฉ์ ์ ๋ณด ์ ์ฅํ๊ธฐ:ย ์ฌ์ฉ์ ์นด์นด์ค๊ณ์ ์ ์ฌ์ฉ์ ์ ์(Custom)ํ ์๋น์ค ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํฉ๋๋ค.
โข
๋์ ๋ด์ญ ํ์ธํ๊ธฐ:ย ์๋น์ค์์ ํ์ฌ ์ฌ์ฉ ์ค์ด๊ฑฐ๋ ์ฌ์ฉ์๊ฐ ๋์ํ ๋์ ํญ๋ชฉ์ ํ์ธํฉ๋๋ค.
โข
๋์ ์ฒ ํํ๊ธฐ:ย ๋ถํ์ํ ๋์ ํญ๋ชฉ์ ๋ํด ์ฌ์ฉ์ ๋์๋ฅผ ์ฒ ํํฉ๋๋ค.
์นด์นด์ค ๋ก๊ทธ์ธ - Kakao developers
์นด์นด์ค ๋ก๊ทธ์ธ ์์ํ๊ธฐ
์์ํ๊ธฐ
์ ํ๋ฆฌ์ผ์ด์ ์ถ๊ฐํ๊ธฐ
์นด์นด์ค ์ ํ๋ฆฌ์ผ์ด์ ์ค์ ํ๊ธฐ
์ฑ ์ค์
์ฑ ํค
REST API ํค ๋ณต์ฌ
ํ๋ซํผ
์ฌ์ดํธ ๋๋ฉ์ธ ๋ฑ๋ก
์ ํ ์ค์
์นด์นด์ค ๋ก๊ทธ์ธ
ํ์ฑํ ์ค์ ON
Redirect URI ๋ฑ๋ก
๋์ ํญ๋ชฉ
๋๋ค์
ํ๋กํ ์ฌ์ง
์นด์นด์ค ๊ณ์ (์ด๋ฉ์ผ)
๋ณด์
Client Secret ํค ๋ฐ๊ธ
Spring Security x OAuth x ์นด์นด์ค ์ฐ๋ํ๊ธฐ
1.
ํ๋ก์ ํธ ์์ฑ
2.
์์กด์ฑ ์ถ๊ฐ
a.
์ฃผ์ ์์กด์ฑ
i.
Spring Security
ii.
OAuth2 Client
b.
๊ธฐ๋ณธ ์์กด์ฑ
i.
Spring Web
ii.
SpringBoot Devtools
iii.
Lombok
iv.
Thymeleaf
v.
MySQL Driver
vi.
MyBatis Framework
3.
ํ๋ก์ ํธ ์ค์
a.
properties profile ํ์ผ ์์ฑ
i.
application-oauth-kakao.properties
b.
properties profile ํฌํจํ๊ธฐ(include)
i.
application.properties
4.
์คํ๋ง ์ํ๋ฆฌํฐ ์ค์
ํ๋ก์ ํธ ์์ฑ
1.
๋ช
๋ น ํ๋ ํธ [ctrl + shift + P]
2.
Create a gradle Project ์
๋ ฅ
a.
ํ๋ก์ ํธ ์ค์
i.
Spring Boot Version
ii.
Language
iii.
Group Id
iv.
Artifact Id
v.
packaging type
vi.
Java version
b.
์์กด์ฑ ์ค์
i.
Spring Web
ii.
Spring boot devtools
iii.
Lombok
iv.
Thymeleaf
v.
MySQL Driver
vi.
Mybatis Framework
vii.
Spring Security
viii.
OAuth2 Client
build.gradle
plugins {
id 'java'
id 'war'
id 'org.springframework.boot' version '2.7.17'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
}
group = 'com.aloha'
version = '0.0.1-SNAPSHOT'
java {
sourceCompatibility = '17'
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
annotationProcessor 'org.projectlombok:lombok'
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
}
tasks.named('test') {
useJUnitPlatform()
}
Plain Text
๋ณต์ฌ
๋ช ๋ น ํ๋ ํธ [ctrl + shift + P]
Create a gradle Project ์ ๋ ฅ
ํ๋ก์ ํธ ์ค์
1.
Spring Boot Version
2.
Language
3.
Group Id
4.
Artifact Id
5.
packaging type
6.
Java version
Spring Boot Version
Language
Group Id
Artifact Id
packaging type
Java version
์์กด์ฑ ์ค์
1.
Spring Web
2.
Spring boot devtools
3.
Lombok
4.
Thymeleaf
5.
MySQL Driver
6.
Mybatis Framework
7.
Spring Security
8.
OAuth2 Client
Spring Web
Spring boot devtools
Lombok
Thymeleaf
MySQL Driver
Mybatis Framework
Spring Security
OAuth2 Client
ํ๋ก์ ํธ ์ค์
properties profile ํ์ผ ์์ฑ
application-oauth-kakao.properties
#Kakao OAuth Settings
spring.security.oauth2.client.registration.kakao.client-id=[REST API ํค]
spring.security.oauth2.client.registration.kakao.client-secret=[Client Secret ์ฝ๋]
spring.security.oauth2.client.registration.kakao.redirect-uri=http://localhost:8080/login/oauth2/code/kakao
spring.security.oauth2.client.registration.kakao.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.kakao.scope=profile_nickname, account_email, profile_image
spring.security.oauth2.client.registration.kakao.client-name=Kakao
spring.security.oauth2.client.registration.kakao.client-authentication-method=POST
spring.security.oauth2.client.provider.kakao.authorization-uri=https://kauth.kakao.com/oauth/authorize
spring.security.oauth2.client.provider.kakao.token-uri=https://kauth.kakao.com/oauth/token
spring.security.oauth2.client.provider.kakao.user-info-uri=https://kapi.kakao.com/v2/user/me
spring.security.oauth2.client.provider.kakao.user-name-attribute=id
Plain Text
๋ณต์ฌ
application-oauth-kakao.properties (์ค๋ช ํฌํจ)
#Kakao OAuth Settings
# client-id : REST API KEY
spring.security.oauth2.client.registration.kakao.client-id=[REST API ํค]
# client-secret : ๋ด ์ ํ๋ฆฌ์ผ์ด์
> ๋ณด์ > Client secret
spring.security.oauth2.client.registration.kakao.client-secret=[Client Secret ์ฝ๋]
# redirect-uri : ์ฌ์ฉ์๊ฐ ์นด์นด์ค๋ก ๋ก๊ทธ์ธ ํ ๋์์ฌ ์๋ฒ์ URL
spring.security.oauth2.client.registration.kakao.redirect-uri=http://localhost:8080/login/oauth2/code/kakao
# authorization-grant-type : ์ก์ธ์ค ํ ํฐ ์์ฒญ ์, ์ ํ์ ์ง์ ํ๋ ํค๋ ์์ฑ
spring.security.oauth2.client.registration.kakao.authorization-grant-type=authorization_code
# scope : ์ฌ์ฉ์ ์ ๋ณด ์์ฒญ ๋ฒ์๋ฅผ ์ง์ ํ๋ ์์ฑ
spring.security.oauth2.client.registration.kakao.scope=profile_nickname, account_email, profile_image
# client-name : ํด๋ผ์ด์ธํธ๋ฅผ ๊ตฌ๋ถํ๊ธฐ ์ํ ์ด๋ฆ
spring.security.oauth2.client.registration.kakao.client-name=Kakao
# client-authentication-method : ์ธ์ฆ ์๋ฒ๋ก ์์ฒญ ์, ์ง์ ํ ์์ฒญ ๋ฉ์๋
spring.security.oauth2.client.registration.kakao.client-authentication-method=POST
# authorization-uri : ์ธ๊ฐ ์ฝ๋ ์์ฒญ URI (์ธ์ฆ ์๋ฒ)
spring.security.oauth2.client.provider.kakao.authorization-uri=https://kauth.kakao.com/oauth/authorize
# token-uri : ์ก์ธ์ค ํ ํฐ ์์ฒญ URI (์ธ์ฆ ์๋ฒ)
spring.security.oauth2.client.provider.kakao.token-uri=https://kauth.kakao.com/oauth/token
# user-info-uri : ์ฌ์ฉ์ ์ ๋ณด ์์ฒญ URI (๋ฆฌ์์ค ์๋ฒ)
spring.security.oauth2.client.provider.kakao.user-info-uri=https://kapi.kakao.com/v2/user/me
# user-name-attribute : ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ๊ณ ์ ์๋ณ๊ฐ ํค ์์ฑ
spring.security.oauth2.client.provider.kakao.user-name-attribute=id
Plain Text
๋ณต์ฌ
REST API ๊ฐ์ ธ์ค๊ธฐ
2.
๋ด ์ ํ๋ฆฌ์ผ์ด์
3.
์ ํ๋ฆฌ์ผ์ด์
์ ํ
4.
[์ฑ ์ค์ ] > [์ฑ ํค]
a.
๋ค์ดํธ๋ธ ์ฑ ํค
b.
REST API ํค
c.
JavaScript ํค
d.
Admin ํค
์ฌ๊ธฐ์ REST API ํค๋ฅผ ๋ณต์ฌํด์ spring.security.oauth2.client.registration.kakao.client-id ์์ฑ๊ฐ์ผ๋ก ์์ฑํฉ๋๋ค.
# client-id : REST API KEY
spring.security.oauth2.client.registration.kakao.client-id=[REST API ํค]
Plain Text
๋ณต์ฌ
Client Secret ๊ฐ์ ธ์ค๊ธฐ
2.
๋ด ์ ํ๋ฆฌ์ผ์ด์
3.
์ ํ๋ฆฌ์ผ์ด์
์ ํ
4.
[์ ํ ์ค์ ] > [์นด์นด์ค ๋ก๊ทธ์ธ] > [๋ณด์]
a.
์ฝ๋
properties profile ํฌํจํ๊ธฐ(include)
1.
ํ๋กํ ํ์ผ ์์ฑ
2.
ํ๋กํ ํ์ผ ํฌํจ
ํ๋กํ ํ์ผ ์์ฑ
ํ๋กํ ํ์ผ์ ๋ค์๊ณผ ๊ฐ์ด ์์ฑํฉ๋๋ค.
application-[ํ๋กํ์ด๋ฆ].properties
Plain Text
๋ณต์ฌ
์ฌ๊ธฐ์๋ ์ด๋ ๊ฒ ์นด์นด์ค ๋ก๊ทธ์ธ ๊ด๋ จ ์์ฑ์ ๋ด๊ณ ์๋ ํ๋กํ ํ์ผ์ ์์ฑํ์์ต๋๋ค.
application-oauth-kakao.properties
Plain Text
๋ณต์ฌ
ํ๋กํ ํ์ผ ํฌํจ
ํ๋กํ ํ์ผ์ application.properties ํ์ผ์์ ๋ค์๊ณผ ๊ฐ์ด ์์ฑ์ ์์ฑํ๋ฉด ํฌํจ์ํฌ ์
์์ต๋๋ค.
โข
application.properties
spring.profiles.include=[ํ๋กํ์ด๋ฆ]
Plain Text
๋ณต์ฌ
์ฌ๊ธฐ์๋ oauth-kakao ์ด๋ผ๋ ์ด๋ฆ์ ๊ฐ์ง ํ๋กํ ํ์ผ์ ํฌํจ์ํต๋๋ค.
โข
application.properties
spring.profiles.include=oauth-kakao
Plain Text
๋ณต์ฌ
application.properties
spring.application.name=kakao
# profile ํ๋กํผํฐ ํ์ผ ํฌํจํ๊ธฐ
# application-[ํ๋กํ์ด๋ฆ].properties
# application-oauth-kakao.properties
spring.profiles.include=oauth-kakao
Plain Text
๋ณต์ฌ
์คํ๋ง ์ํ๋ฆฌํฐ ์ค์
1.
SecurityConfig.java ํ์ผ ์์ฑ
a.
config/SecurityConfig.java
2.
์ฝ๋ ์์ฑ
package com.aloha.kakao.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
// ์คํ๋ง ์ํ๋ฆฌํฐ ์ค์ ๋ฉ์๋
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// OAuth ๋ก๊ทธ์ธ ์ค์
http.oauth2Login(login -> login
.loginPage("/login")
);
return http.build();
}
}
Java
๋ณต์ฌ
์ปจํธ๋กค๋ฌ
1.
HomeController.java
HomeController.java
package com.aloha.kakao.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class HomeController {
@GetMapping({"/", ""})
public String home() {
return "index";
}
@GetMapping("/login")
public String login() {
return "login";
}
}
Java
๋ณต์ฌ
ํ๋ฉด
2.
๋ฉ์ธ ํ๋ฉด
a.
index.html
3.
๋ก๊ทธ์ธ ํ๋ฉด
a.
login.html
์นด์นด์ค ๋์์ธ ๊ฐ์ด๋
์นด์นด์ค ๋์์ธ ์ฌ์ดํธ์ ๊ฐ๋ฉด, ์นด์นด์ค ๋ก๊ทธ์ธ ๋ฒํผ์ ์ด๋ฏธ์ง๋ก ์ ๊ณตํฉ๋๋ค.
์ฌ๊ธฐ์ ์ ์ ํ ์นด์นด์ค ๋ก๊ทธ์ธ ๋ฒํผ ์ด๋ฏธ์ง๋ฅผ ๊ฐ์ ธ์์ ๋ก๊ทธ์ธ ํ์ด์ง์ ์ถ๋ ฅํฉ๋๋ค.
๋ฉ์ธ ํ๋ฉด
index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
<head>
<meta charset="UTF-8">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>์นด์นด์ค ๋ก๊ทธ์ธ๐ - ALOHA CLASS๐ด</title>
<!-- ํ๋น์ฝ -->
<link rel="icon" href="/img/logo.png" type="image/x-icon">
<!-- ์ธ๋ค์ผ ์ด๋ฏธ์ง ์ค์ -->
<meta property="og:image" content="https://i.imgur.com/tXd2rVi.png">
<!-- ์น ํ์ด์ง ์ค๋ช
(์ ํ ์ฌํญ) -->
<meta property="og:description" content="ALOHA CLASS๐ด - ์์
๋ก๊ทธ์ธ">
<!-- ์น ํ์ด์ง URL -->
<meta property="og:url" content="">
<!-- ์น ํ์ด์ง ์ ๋ชฉ -->
<meta name="title" content="์นด์นด์ค ๋ก๊ทธ์ธ๐ - ALOHA CLASS๐ด">
<meta property="og:title" content="์นด์นด์ค ๋ก๊ทธ์ธ๐ - ALOHA CLASS๐ด">
<!-- ์น ํ์ด์ง ํ์
(์น์ฌ์ดํธ, ๊ธฐ์ฌ, ์ ํ ๋ฑ) -->
<meta property="og:type" content="website">
<!-- ๊ฒ์์ด -->
<meta name="keywords" content="์์
๋ก๊ทธ์ธ์๋ฐ ์น๊ฐ๋ฐ, ALOHA CLASS, ์๋กํ ํด๋์ค">
<meta name="robots" content="index, follow">
<!-- ์ฌ์ดํธ ๋งต -->
<link rel="sitemap" href="/static/sitemap.xml">
<!-- bootstrap lib -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-4bw+/aepP/YC94hEpVNVgiZdgIC5+VKNBQNGCHeKRQN+PtmoHDEXuppvnDJzQIu9" crossorigin="anonymous">
<!-- Noto Sans font -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Noto+Sans:400,700&display=swap">
<!-- material design icon -->
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<link rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200">
</head>
<body>
<div class="container col-6 col-lg-4">
<div class="px-4 py-5 mt-5 text-center">
<h1 class="display-5 fw-bold text-body-emphasis">๋ก๊ทธ์ธ</h1>
</div>
<!-- ๋น ๋ก๊ทธ์ธ ์ -->
<th:block sec:authorize="isAnonymous()">
<div class="d-grid gap-2">
<a href="/login" class="btn btn-lg btn-primary">๋ก๊ทธ์ธ</a>
</div>
</th:block>
<!-- ๋ก๊ทธ์ธ ์ -->
<th:block sec:authorize="isAuthenticated()">
<div class="card" th:if="${session.user != null}">
<div class="inner p-4">
<div class="d-flex flex-column align-items-center">
<div class="item my-2">
<!-- ํ๋กํ ์ฌ์ง -->
<th:block th:if="${session.user.profile == null}">
<img src="/img/profile.png" class="rounded-circle shadow-4 border" width="110" alt="ํ๋กํ" >
</th:block>
<th:block th:if="${session.user.profile != null}">
<img th:src="${session.user.profile}" class="rounded-circle shadow-4 border" width="110" alt="ํ๋กํ">
</th:block>
</div>
<div class="item my-2">
<!-- ๋๋ค์ -->
<h3 th:text="${session.user.name}"></h3>
</div>
<div class="item my-2">
<!-- ์ด๋ฉ์ผ -->
<h3 th:text="${session.user.email}"></h3>
</div>
</div>
</div>
</div>
<form action="/logout" method="post">
<!-- CSRF TOKEN -->
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}">
<div class="d-grid gap-2">
<button type="submit" class="btn btn-lg btn-primary">๋ก๊ทธ์์</button>
</div>
</form>
</th:block>
</div>
</body>
</html>
HTML
๋ณต์ฌ
๋ก๊ทธ์ธ ํ๋ฉด
login.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
<head>
<meta charset="UTF-8">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>์นด์นด์ค ๋ก๊ทธ์ธ๐ - ALOHA CLASS๐ด</title>
<!-- ํ๋น์ฝ -->
<link rel="icon" href="/img/logo.png" type="image/x-icon">
<!-- ์ธ๋ค์ผ ์ด๋ฏธ์ง ์ค์ -->
<meta property="og:image" content="https://i.imgur.com/tXd2rVi.png">
<!-- ์น ํ์ด์ง ์ค๋ช
(์ ํ ์ฌํญ) -->
<meta property="og:description" content="ALOHA CLASS๐ด - ์์
๋ก๊ทธ์ธ">
<!-- ์น ํ์ด์ง URL -->
<meta property="og:url" content="">
<!-- ์น ํ์ด์ง ์ ๋ชฉ -->
<meta name="title" content="์นด์นด์ค ๋ก๊ทธ์ธ๐ - ALOHA CLASS๐ด">
<meta property="og:title" content="์นด์นด์ค ๋ก๊ทธ์ธ๐ - ALOHA CLASS๐ด">
<!-- ์น ํ์ด์ง ํ์
(์น์ฌ์ดํธ, ๊ธฐ์ฌ, ์ ํ ๋ฑ) -->
<meta property="og:type" content="website">
<!-- ๊ฒ์์ด -->
<meta name="keywords" content="์์
๋ก๊ทธ์ธ์๋ฐ ์น๊ฐ๋ฐ, ALOHA CLASS, ์๋กํ ํด๋์ค">
<meta name="robots" content="index, follow">
<!-- ์ฌ์ดํธ ๋งต -->
<link rel="sitemap" href="/static/sitemap.xml">
<!-- bootstrap lib -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Noto Sans font -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Noto+Sans:400,700&display=swap">
<!-- material design icon -->
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200">
</head>
<body>
<div class="container col-12 col-md-6 col-lg-4">
<div class="px-4 py-5 mt-5 text-center">
<h1 class="display-5 fw-bold text-body-emphasis">๋ก๊ทธ์ธ</h1>
</div>
<!-- ๋ก๊ทธ์ธ ์์ญ -->
<main class="form-signin login-box w-100 m-auto">
<form action="/login" method="post">
<!-- CSRF TOKEN -->
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}">
<div class="form-floating">
<input type="text" class="form-control" id="floatingInput" name="username" value="" placeholder="์์ด๋"
autofocus th:value="${userId}">
<label for="floatingInput">์์ด๋</label>
</div>
<div class="form-floating">
<input type="password" class="form-control" id="floatingPassword" name="password" placeholder="๋น๋ฐ๋ฒํธ">
<label for="floatingPassword">๋น๋ฐ๋ฒํธ</label>
</div>
<div class="form-check text-start my-3 d-flex justify-content-around">
<div class="item">
<input class="form-check-input" type="checkbox" name="remember-id" id="flexCheckDefault1" th:checked="${rememberId}">
<label class="form-check-label" for="flexCheckDefault1">์์ด๋ ์ ์ฅ</label>
</div>
<div class="item">
<input class="form-check-input" type="checkbox" name="remember-me" id="flexCheckDefault2">
<label class="form-check-label" for="flexCheckDefault2">์๋ ๋ก๊ทธ์ธ</label>
</div>
</div>
<!-- ๋ก๊ทธ์ธ ์๋ฌ -->
<th:block th:if="${param.error}">
<p class="text-center text-danger">์์ด๋ ๋๋ ๋น๋ฐ๋ฒํธ๋ฅผ ์๋ชป ์
๋ ฅํ์ต๋๋ค.</p>
</th:block>
<div class="d-grid gap-2">
<button class="btn btn-lg btn-primary w-100 py-2" type="submit">๋ก๊ทธ์ธ</button>
<a href="/join" class="btn btn-lg btn-success w-100 py-2">ํ์๊ฐ์
</a>
<hr>
<a href="/oauth2/authorization/kakao">
<img src="/img/kakao_login_large.png" width="100%" alt="์นด์นด์ค ๋ก๊ทธ์ธ">
</a>
</div>
</form>
</main>
</div>
<!-- bootstrap -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
HTML
๋ณต์ฌ