๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

์Šคํ”„๋ง ๋ถ€ํŠธ์™€ ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ ํ†ตํ•ฉ: JWT์™€ OAuth2๋กœ ์ธ์ฆ ๋ฐ ์ธ๊ฐ€ ๊ตฌํ˜„ํ•˜๊ธฐ

mrmount 2024. 10. 21.

 

์Šคํ”„๋ง ๋ถ€ํŠธ(Spring Boot) ์™€ ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ(Spring Security) ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ธ์ฆ(Authentication) ๊ณผ ์ธ๊ฐ€(Authorization) ๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” ์ธ์ฆ๊ณผ ์ธ๊ฐ€ ๊ฐœ๋… ์„ ์„ค๋ช…ํ•˜๊ณ , JWT(Json Web Token)๋ฅผ ํ™œ์šฉํ•œ ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌ ์™€ OAuth 2.0์„ ์ด์šฉํ•œ ์†Œ์…œ ๋กœ๊ทธ์ธ ๊ตฌํ˜„ ๋ฐฉ๋ฒ•์„ ์˜ˆ์ œ์™€ ํ•จ๊ป˜ ์•Œ์•„๋ด…๋‹ˆ๋‹ค.

 


 

 

๋ชฉ์ฐจ

  1. ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ์˜ ์ธ์ฆ๊ณผ ์ธ๊ฐ€ ๊ฐœ๋…
  2. JWT๋ฅผ ํ™œ์šฉํ•œ ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌ
  3. OAuth 2.0 ๋กœ๊ทธ์ธ ๊ตฌํ˜„ํ•˜๊ธฐ
  4. ์ธ์ฆ๊ณผ ์ธ๊ฐ€์˜ ์ตœ์‹  ํŠธ๋ Œ๋“œ์™€ ์ค‘์š”์„ฑ
  5. JWT์™€ OAuth 2.0 ์˜ˆ์ œ ์ฝ”๋“œ ๋ฐ ์‹คํ–‰ ๋ฐฉ๋ฒ•

 


 

1. ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ์˜ ์ธ์ฆ๊ณผ ์ธ๊ฐ€ ๊ฐœ๋…

์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ ๋Š” ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ์— ํ†ตํ•ฉ๋œ ๋ณด์•ˆ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋กœ, ์ธ์ฆ ๊ณผ ์ธ๊ฐ€ ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ ์ตœ์ ํ™”๋œ ์†”๋ฃจ์…˜์ž…๋‹ˆ๋‹ค.

  • ์ธ์ฆ(Authentication) : ์‚ฌ์šฉ์ž๊ฐ€ ๋ˆ„๊ตฌ์ธ์ง€ ํ™•์ธํ•˜๋Š” ์ ˆ์ฐจ์ž…๋‹ˆ๋‹ค. (์˜ˆ: ๋กœ๊ทธ์ธ)
  • ์ธ๊ฐ€(Authorization) : ์‚ฌ์šฉ์ž๊ฐ€ ์–ด๋–ค ๋ฆฌ์†Œ์Šค์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š”์ง€๋ฅผ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค. (์˜ˆ: ๊ด€๋ฆฌ์ž ๊ถŒํ•œ๋งŒ ํŠน์ • ํŽ˜์ด์ง€ ์ ‘๊ทผ)
๊ตฌ๋ถ„ ์„ค๋ช… ์˜ˆ์‹œ
์ธ์ฆ ์‚ฌ์šฉ์ž๊ฐ€ ์˜ฌ๋ฐ”๋ฅธ ์ž๊ฒฉ ์ฆ๋ช…์„ ์ œ๊ณตํ•˜๋Š”์ง€ ํ™•์ธ ID์™€ ๋น„๋ฐ€๋ฒˆํ˜ธ๋กœ ๋กœ๊ทธ์ธ
์ธ๊ฐ€ ์‚ฌ์šฉ์ž๊ฐ€ ๋ฆฌ์†Œ์Šค์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ์ด ์žˆ๋Š”์ง€ ํ™•์ธ ๊ด€๋ฆฌ์ž๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ํŽ˜์ด์ง€




 

2. JWT๋ฅผ ํ™œ์šฉํ•œ ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌ

 

JWT๋ž€ ๋ฌด์—‡์ธ๊ฐ€?

JWT(Json Web Token) ๋Š” ์‚ฌ์šฉ์ž ์ธ์ฆ ์ •๋ณด๋ฅผ ์•”ํ˜ธํ™” ํ•œ ํ† ํฐ์œผ๋กœ, ๋กœ๊ทธ์ธ ํ›„ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ํ† ํฐ์„ ๋ฐœ๊ธ‰ํ•˜๊ณ  ์ดํ›„ ์š”์ฒญ๋งˆ๋‹ค ์ด ํ† ํฐ์„ ์‚ฌ์šฉํ•ด ์ธ์ฆํ•ฉ๋‹ˆ๋‹ค.

JWT ์ธ์ฆ ํ๋ฆ„

  1. ์‚ฌ์šฉ์ž๊ฐ€ ID์™€ ๋น„๋ฐ€๋ฒˆํ˜ธ๋กœ ๋กœ๊ทธ์ธ ์š”์ฒญ
  2. ์„œ๋ฒ„์—์„œ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ํ™•์ธ ํ›„ JWT ๋ฐœ๊ธ‰
  3. ํด๋ผ์ด์–ธํŠธ๋Š” JWT๋ฅผ ์ €์žฅํ•˜๊ณ  ์ดํ›„ ์š”์ฒญ์˜ ํ—ค๋”์— ํฌํ•จ ํ•ด ์„œ๋ฒ„๋กœ ์ „์†ก
  4. ์„œ๋ฒ„๋Š” JWT๋ฅผ ๊ฒ€์ฆํ•ด ์š”์ฒญ ์ฒ˜๋ฆฌ

JWT ๋ฐœ๊ธ‰ ๋ฐ ์ธ์ฆ ์˜ˆ์ œ ์ฝ”๋“œ

 

pom.xml ์˜์กด์„ฑ ์ถ”๊ฐ€

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>0.11.2</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-impl</artifactId>
    <version>0.11.2</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <version>0.11.2</version>
</dependency>

 

JwtTokenProvider.java (JWT ํ† ํฐ ์ƒ์„ฑ ๋ฐ ๊ฒ€์ฆ)

package com.example.demo.security;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component
public class JwtTokenProvider {

    private final String SECRET_KEY = "mySecretKey";
    private final long EXPIRATION_TIME = 86400000; // 24์‹œ๊ฐ„

    public String generateToken(String username) {
        return Jwts.builder()
                .setSubject(username)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
                .signWith(SignatureAlgorithm.HS512, SECRET_KEY)
                .compact();
    }

    public String validateAndGetUsername(String token) {
        Claims claims = Jwts.parser()
                .setSigningKey(SECRET_KEY)
                .parseClaimsJws(token)
                .getBody();
        return claims.getSubject();
    }
}

 

SecurityConfig.java (์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ ์„ค์ •)

package com.example.demo.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/api/login").permitAll()
            .anyRequest().authenticated();
    }
}

JWT ๋ฐœ๊ธ‰ ๋ฐ ์ธ์ฆ ํ…Œ์ŠคํŠธ

  • POST /api/login : ๋กœ๊ทธ์ธ ํ›„ JWT ๋ฐœ๊ธ‰
  • ์ดํ›„ ์š”์ฒญ์— Authorization ํ—ค๋” ๋กœ Bearer {token} ์„ ํฌํ•จํ•ด ์ธ์ฆ ์ฒ˜๋ฆฌ

 


 

3. OAuth 2.0 ๋กœ๊ทธ์ธ ๊ตฌํ˜„ํ•˜๊ธฐ

 

OAuth 2.0์ด๋ž€?

OAuth 2.0 ์€ ๊ตฌ๊ธ€, ํŽ˜์ด์Šค๋ถ, ์นด์นด์˜ค ๋“ฑ ์†Œ์…œ ๋กœ๊ทธ์ธ ์„ ๊ตฌํ˜„ํ•  ๋•Œ ์‚ฌ์šฉ๋˜๋Š” ํ”„๋กœํ† ์ฝœ์ž…๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ง์ ‘ ๋กœ๊ทธ์ธํ•˜์ง€ ์•Š๊ณ , ์†Œ์…œ ๊ณ„์ •์œผ๋กœ ์ธ์ฆ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค๋‹ˆ๋‹ค.

OAuth 2.0 ๋กœ๊ทธ์ธ ํ๋ฆ„

  1. ์‚ฌ์šฉ์ž๊ฐ€ ๊ตฌ๊ธ€ ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ ํด๋ฆญ
  2. ๊ตฌ๊ธ€์—์„œ ์ธ์ฆ ํ›„ ์•ก์„ธ์Šค ํ† ํฐ ๋ฐœ๊ธ‰
  3. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ํ† ํฐ์„ ๋ฐ›์•„ ์‚ฌ์šฉ์ž๋ฅผ ์‹๋ณ„

OAuth 2.0 ์„ค์ • ์˜ˆ์ œ

 

pom.xml ์˜์กด์„ฑ ์ถ”๊ฐ€

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>

 

application.yml ์„ค์ •

spring:
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: YOUR_GOOGLE_CLIENT_ID
            client-secret: YOUR_GOOGLE_CLIENT_SECRET
            redirect-uri: "{baseUrl}/login/oauth2/code/google"
            scope: email, profile
            client-authentication-method: basic
            authorization-grant-type: authorization_code
            provider:
              google:
                authorization-uri: https://accounts.google.com/o/oauth2/auth
                token-uri: https://oauth2.googleapis.com/token
                user-info-uri: https://www.googleapis.com/oauth2/v3/userinfo

 

SecurityConfig.java (OAuth 2.0 ์„ค์ •)

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.oauth2Login()
        .loginPage("/login")
        .defaultSuccessUrl("/home", true);
}

์‹คํ–‰ ๊ฒฐ๊ณผ

  1. /login ํŽ˜์ด์ง€์—์„œ ๊ตฌ๊ธ€ ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.
  2. ๊ตฌ๊ธ€ ๊ณ„์ •์œผ๋กœ ๋กœ๊ทธ์ธ ํ›„ /home ํŽ˜์ด์ง€๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ๋ฉ๋‹ˆ๋‹ค.

 


 

4. ์ธ์ฆ๊ณผ ์ธ๊ฐ€์˜ ์ตœ์‹  ํŠธ๋ Œ๋“œ์™€ ์ค‘์š”์„ฑ

  • JWT ๋Š” ๋ฌด์ƒํƒœ(stateless) ์„œ๋ฒ„ ์™€ ์ž˜ ๋งž์•„ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ์•„ํ‚คํ…์ฒ˜ ์—์„œ ๋งŽ์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  • OAuth 2.0 ์€ ์†Œ์…œ ๋กœ๊ทธ์ธ ์„ ์ œ๊ณตํ•˜๋ฉฐ, ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ๊ฐœ์„ ํ•˜๊ณ  ๋ณด์•ˆ์„ ๊ฐ•ํ™”ํ•ฉ๋‹ˆ๋‹ค.
  • 2024๋…„ ๊ธฐ์ค€, ํด๋ผ์šฐ๋“œ ํ™˜๊ฒฝ ์—์„œ๋Š” JWT์™€ OAuth 2.0์„ ํ™œ์šฉํ•œ ์ธ์ฆ ๋ฐ ์ธ๊ฐ€๊ฐ€ ํ•„์ˆ˜์ ์ธ ๊ธฐ์ˆ ๋กœ ์ž๋ฆฌ ์žก๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

 


 

๊ด€๋ จ ๋งํฌ


Spring Security ๊ณต์‹ ๋ฌธ์„œ๐Ÿ‘†

JWT ๊ณต์‹ ์‚ฌ์ดํŠธ๐Ÿ‘†

๊ตฌ๊ธ€ OAuth 2.0 ๋ฌธ์„œ๐Ÿ‘†

Spring Boot์™€ JWT ํŠœํ† ๋ฆฌ์–ผ๐Ÿ‘†

OAuth 2.0 ๊ฐœ๋… ์ •๋ฆฌ๐Ÿ‘†

Spring Boot ๊ณต์‹ ์‚ฌ์ดํŠธ๐Ÿ‘†




FAQ

 

1. JWT๋Š” ์–ธ์ œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‚˜์š”?

  • JWT๋Š” ๋ฌด์ƒํƒœ(stateless) ์ธ์ฆ ์ด ํ•„์š”ํ•œ RESTful API์—์„œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

2. OAuth 2.0๊ณผ JWT์˜ ์ฐจ์ด์ ์€ ๋ฌด์—‡์ธ๊ฐ€์š”?

  • OAuth 2.0์€ ์†Œ์…œ ๋กœ๊ทธ์ธ ์— ์‚ฌ์šฉ๋˜๋ฉฐ, JWT๋Š” ์ฃผ๋กœ ํ† ํฐ ๊ธฐ๋ฐ˜ ์ธ์ฆ ์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

3. JWT ํ† ํฐ์€ ์•ˆ์ „ํ•œ๊ฐ€์š”?

  • JWT๋Š” ์„œ๋ช…๋œ ํ† ํฐ ์œผ๋กœ ์œ„๋ณ€์กฐ๊ฐ€ ์–ด๋ ต์ง€๋งŒ, ๋งŒ๋ฃŒ ์‹œ๊ฐ„ ์„ค์ •๊ณผ HTTPS ์‚ฌ์šฉ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

4. OAuth 2.0 ๊ตฌํ˜„ ์‹œ ํด๋ผ์ด์–ธํŠธ ID์™€ ๋น„๋ฐ€ ํ‚ค๋Š” ์–ด๋””์„œ ์–ป๋‚˜์š”?

  • ์†Œ์…œ ์„œ๋น„์Šค(์˜ˆ: ๊ตฌ๊ธ€, ํŽ˜์ด์Šค๋ถ) ๊ฐœ๋ฐœ์ž ์ฝ˜์†”์—์„œ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

5. JWT ํ† ํฐ์ด ๋งŒ๋ฃŒ๋˜๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ•˜๋‚˜์š”?

  • ๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ(refresh token) ์„ ์‚ฌ์šฉํ•ด ์ƒˆ๋กœ์šด JWT๋ฅผ ๋ฐœ๊ธ‰๋ฐ›๋Š” ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

 


 

๋งˆ๋ฌด๋ฆฌ

์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” ์Šคํ”„๋ง ๋ถ€ํŠธ์™€ ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ ๋ฅผ ์‚ฌ์šฉํ•ด JWT ๊ธฐ๋ฐ˜ ์ธ์ฆ ๊ณผ OAuth 2.0 ์†Œ์…œ ๋กœ๊ทธ์ธ ์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค. JWT ๋Š” ๋ฌด์ƒํƒœ ์ธ์ฆ ์— ์ ํ•ฉํ•˜์—ฌ REST API์™€ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ํ™˜๊ฒฝ์—์„œ ๋งŽ์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ OAuth 2.0 ์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ตฌ๊ธ€, ํŽ˜์ด์Šค๋ถ, ์นด์นด์˜ค ์™€ ๊ฐ™์€ ์†Œ์…œ ๊ณ„์ •์„ ํ†ตํ•ด ์‚ฌ์šฉ์ž ์ธ์ฆ์„ ๊ฐ„ํŽธํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด ์‚ฌ์šฉ์ž ๊ฒฝํ—˜(UX)์„ ํฌ๊ฒŒ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ ๋Š” ๋‹ค์–‘ํ•œ ์ธ์ฆ ๋ฐ ์ธ๊ฐ€ ๋ฐฉ๋ฒ•์„ ์ง€์›ํ•˜๋ฉฐ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์œ ์—ฐํ•œ ๋ณด์•ˆ ์„ค์ • ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฒˆ ํฌ์ŠคํŒ…์„ ํ†ตํ•ด ์—ฌ๋Ÿฌ๋ถ„์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์•ˆ์ „ํ•œ ๋ณด์•ˆ ๊ธฐ๋Šฅ ์„ ์ถ”๊ฐ€ํ•ด ๋ณด์„ธ์š”.

๋Œ“๊ธ€