카테고리 없음

spring securtiy + 인증 서버 로그인 로직

jw-backend 2024. 7. 1. 19:13
반응형

인증 과정 흐름

  1. 클라이언트 요청:
    • 사용자가 로그인 폼에 사용자 이름과 비밀번호를 입력합니다.
    • 클라이언트(웹 브라우저 또는 모바일 앱)가 이 자격 증명을 포함하여 인증 서버에 로그인 요청을 보냅니다.
  2. 인증 서버 처리:
    • 인증 서버는 요청을 수신하고, 사용자 이름과 비밀번호를 추출합니다.
    • 데이터베이스에서 해당 사용자 이름에 대한 정보를 조회합니다.
    • 데이터베이스에 저장된 비밀번호(일반적으로 해시된 형태)와 사용자가 입력한 비밀번호를 비교합니다.
  3. 자격 증명 확인:
    • 비밀번호가 일치하면, 사용자가 유효한 자격 증명을 제공한 것으로 간주됩니다.
    • 비밀번호가 일치하지 않으면, 인증 실패로 간주하고 적절한 오류 메시지를 반환합니다.
  4. JWT 토큰 발급:
    • 자격 증명이 유효하다면, 인증 서버는 JWT 토큰을 생성합니다.
    • JWT 토큰에는 사용자 정보와 토큰의 유효기간, 서명 등이 포함됩니다.
    • 생성된 JWT 토큰을 클라이언트에 반환합니다.

예시 코드 (Spring Security 기반)

다음은 Spring Security와 JWT를 사용하여 위 과정을 구현하는 예시 코드입니다.

1. 사용자 엔티티 및 리포지토리

java

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String username;
    private String password; // 저장 시 해시된 비밀번호
    // 기타 사용자 정보
}

public interface UserRepository extends JpaRepository<User, Long> {
    Optional<User> findByUsername(String username);
}

2. 인증 서비스

java

@Service
public class AuthService {
    @Autowired
    private UserRepository userRepository;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private JwtTokenProvider jwtTokenProvider;

    public String login(String username, String password) {
        User user = userRepository.findByUsername(username)
                .orElseThrow(() -> new UsernameNotFoundException("User not found"));

        if (!passwordEncoder.matches(password, user.getPassword())) {
            throw new BadCredentialsException("Invalid password");
        }

        return jwtTokenProvider.createToken(username);
    }
}

3. JWT 토큰 생성기

java

@Component
public class JwtTokenProvider {
    private final String secretKey = "secret"; // 실제로는 더 복잡한 키를 사용해야 함
    private final long validityInMilliseconds = 3600000; // 1시간

    public String createToken(String username) {
        Claims claims = Jwts.claims().setSubject(username);
        Date now = new Date();
        Date validity = new Date(now.getTime() + validityInMilliseconds);

        return Jwts.builder()
                .setClaims(claims)
                .setIssuedAt(now)
                .setExpiration(validity)
                .signWith(SignatureAlgorithm.HS256, secretKey)
                .compact();
    }
}

4. 로그인 컨트롤러

java

@RestController
@RequestMapping("/auth")
public class AuthController {
    @Autowired
    private AuthService authService;

    @PostMapping("/login")
    public ResponseEntity<?> login(@RequestBody LoginRequest loginRequest) {
        String token = authService.login(loginRequest.getUsername(), loginRequest.getPassword());
        return ResponseEntity.ok(new JwtResponse(token));
    }
}

5. 요청 및 응답 모델

java

public class LoginRequest {
    private String username;
    private String password;
    // getters and setters
}

public class JwtResponse {
    private String token;

    public JwtResponse(String token) {
        this.token = token;
    }
    // getters and setters
}

요약

  1. 클라이언트가 사용자 이름과 비밀번호를 포함하여 인증 서버에 로그인 요청을 보냅니다.
  2. 인증 서버는 데이터베이스에서 사용자 이름을 조회하고, 저장된 비밀번호와 비교합니다.
  3. 자격 증명이 유효하면, JWT 토큰을 생성하여 클라이언트에 반환합니다.
  4. 클라이언트는 이후 요청에서 이 JWT 토큰을 사용하여 인증을 수행합니다.

이 과정을 통해 사용자 자격 증명을 안전하게 확인하고, JWT 토큰을 발급할 수 있습니다.