11월 30일-OAuth 2.0 인증 흐름

Yullgiii·2023년 11월 30일
0
post-thumbnail

OAuth 2.0 인증 흐름

OAuth 2.0 인증 흐름은 여러 가지가 있고, 각각의 특징과 적용 시나리오에 따라 선택한다. 주요 인증 흐름에는 Authorization Code Grant, Implicit Grant, Client Credentials Grant, Resource Owner Password Credentials Grant가 있다.

Authorization Code Grant

가장 일반적으로 사용되는 인증 흐름으로, 웹 애플리케이션과 서버 간의 인증에 적합하다. 사용자가 애플리케이션에 로그인하여 권한을 부여하면, 애플리케이션은 인증 서버로부터 인가 코드를 받아온다. 이 인가 코드를 사용하여 애플리케이션은 액세스 토큰을 요청하고, 이를 통해 사용자의 데이터에 접근한다.

import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

HttpClient client = HttpClient.newHttpClient();
String authorizationCode = "인가 코드";
String tokenEndpoint = "인증 서버의 토큰 엔드포인트 URL";
String clientId = "클라이언트 ID";
String clientSecret = "클라이언트 시크릿";
String redirectUri = "리다이렉트 URI";

String requestBody = "grant_type=authorization_code&code=" + URLEncoder.encode(authorizationCode, StandardCharsets.UTF_8)
        + "&client_id=" + URLEncoder.encode(clientId, StandardCharsets.UTF_8)
        + "&client_secret=" + URLEncoder.encode(clientSecret, StandardCharsets.UTF_8)
        + "&redirect_uri=" + URLEncoder.encode(redirectUri, StandardCharsets.UTF_8);

HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create(tokenEndpoint))
        .header("Content-Type", "application/x-www-form-urlencoded")
        .POST(HttpRequest.BodyPublishers.ofString(requestBody))
        .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

System.out.println(response.body());

Implicit Grant

주로 클라이언트 측 JavaScript 애플리케이션에 적합한 인증 흐름이다. 사용자가 로그인하고 권한을 부여하면, 애플리케이션은 인증 서버로부터 액세스 토큰을 직접 받아온다. 이 흐름은 인증 코드 교환 단계를 생략하여 인증 과정을 간단하게 처리한다.

var authorizationEndpoint = "인증 서버의 인가 엔드포인트 URL";
var clientId = "클라이언트 ID";
var redirectUri = "리다이렉트 URI";

var url = authorizationEndpoint + "?response_type=token&client_id=" + clientId + "&redirect_uri=" + redirectUri;
var accessToken = extractAccessTokenFromUrl();

Client Credentials Grant

클라이언트 애플리케이션이 사용자 대신 자체 인증을 수행할 때 사용된다. 애플리케이션은 자격증명을 사용하여 인증 서버로부터 액세스 토큰을 직접 요청한다. 이후 해당 토큰을 사용하여 리소스 서버에 접근한다. 이 흐름은 사용자의 개별 인증 과정이 필요하지 않다.

import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

HttpClient client = HttpClient.newHttpClient();
String clientId = "클라이언트 ID";
String clientSecret = "클라이언트 시크릿";
String tokenEndpoint = "인증 서버의 토큰 엔드포인트 URL";

String requestBody = "grant_type=client_credentials&client_id=" + URLEncoder.encode(clientId, StandardCharsets.UTF_8)
        + "&client_secret=" + URLEncoder.encode(clientSecret, StandardCharsets.UTF_8);

HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create(tokenEndpoint))
        .header("Content-Type

Resource Owner Password Credentials Grant

이 인증 흐름은 사용자의 아이디와 비밀번호를 사용하여 직접 인증을 수행한다. 사용자가 애플리케이션에 직접 아이디와 비밀번호를 입력하고, 애플리케이션은 이를 통해 인증 서버로부터 액세스 토큰을 요청하여 받아온다.

import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

HttpClient client = HttpClient.newHttpClient();
String username = "사용자 아이디";
String password = "사용자 비밀번호";
String clientId = "클라이언트 ID";
String clientSecret = "클라이언트 시크릿";
String tokenEndpoint = "인증 서버의 토큰 엔드포인트 URL";

String requestBody = "grant_type=password&username=" + URLEncoder.encode(username, StandardCharsets.UTF_8)
        + "&password=" + URLEncoder.encode(password, StandardCharsets.UTF_8)
        + "&client_id=" + URLEncoder.encode(clientId, StandardCharsets.UTF_8)
        + "&client_secret=" + URLEncoder.encode(clientSecret, StandardCharsets.UTF_8);

HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create(tokenEndpoint))
        .header("Content-Type", "application/x-www-form-urlencoded")
        .POST(HttpRequest.BodyPublishers.ofString(requestBody))
        .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

System.out.println(response.body());

각각의 인증 흐름은 특정한 시나리오에 맞추어 설계되었으며, 사용자 인증과 권한 부여를 위한 다양한 방법을 제공한다. 애플리케이션의 요구 사항과 보안 요건에 따라 적절한 인증 흐름을 선택하는 것이 중요하다.

또한, 이러한 인증 과정에서는 보안에 주의해야 한다. 특히 인증 정보는 암호화된 통신 경로를 통해 전송되어야 하며, 애플리케이션은 받은 토큰을 안전하게 보관하여야 한다. 토큰의 만료 시간이 지나면 새로운 토큰을 요청해야 하며, 이 과정에서는 이전 토큰이 무효화되는 점을 확인해야 한다. 이외에도 각 인증 흐름별로 요구되는 보안 조치가 있으니, 구현 시에는 각각의 특성과 요구 사항을 충분히 이해하고 적용해야 한다.

profile
개발이란 무엇인가..를 공부하는 거북이의 성장일기 🐢

0개의 댓글