Skip to content

higukang/k-oauth

Repository files navigation

K-OAuth

A simple Java OAuth 2.0 library for Korean OAuth providers (Kakao, Naver)

Maven Central License: MIT Java Version

Korean Version (한글 버전 README)

Table of Contents

  1. Installation
  2. Documentation
  3. General Usage
  4. Advanced Features
  5. Error Handling
  6. Inspiration
  7. Contributing

Installation

Maven Central

Official releases are published to Maven Central.

Gradle

Add the following to your build.gradle file:

dependencies {
    implementation 'kr.higu:k-oauth:0.1.2'
}

Maven

<dependency>
  <groupId>kr.higu</groupId>
  <artifactId>k-oauth</artifactId>
  <version>0.1.2</version>
</dependency>

JitPack

JitPack remains available as a secondary channel for GitHub-based snapshot or branch builds.

Gradle

repositories {
    mavenCentral()
    maven { url 'https://jitpack.io' }
}

dependencies {
    implementation 'com.github.higukang:k-oauth:main-SNAPSHOT'
}

IDE Integration (Optional)

If you cannot see the library's source code or Javadoc in your IDE:

  • IntelliJ: Click "Download Sources" in the notification bar or use the Gradle tab to refresh with sources enabled.
  • VS Code: Ensure the "Java Language Support" extension is installed; it typically handles sources automatically.

Documentation

Javadoc is included in the published Maven Central artifacts through the javadoc classifier.

Why Singleton HttpClient?

K-OAuth uses a singleton HttpClient by default to avoid creating a new HTTP client for every OAuth request. Reusing a single client reduces unnecessary overhead, allows the JDK to reuse underlying connections internally, and keeps the library lightweight for common Spring Boot and side-project use cases.

This design favors simplicity and predictable behavior over heavy configuration. If you need more control over the transport layer, you can provide your own IHttpManager through KakaoClient.create(IHttpManager) or NaverClient.create(IHttpManager).

General Usage

Kakao Client

1. Exchange Code for Access Token

KakaoClient kakaoClient = KakaoClient.create();

try {
    KakaoTokenResponse response = kakaoClient.getToken()
        .clientId("YOUR_REST_API_KEY")
        .redirectUri("YOUR_REDIRECT_URI")
        .code("AUTHORIZATION_CODE")
        .clientSecret("YOUR_CLIENT_SECRET") // Optional (null is ignored)
        .build()
        .execute();

    System.out.println("Access Token: " + response.accessToken());
} catch (OAuthException e) {
    e.printStackTrace();
}

2. Refresh Tokens with a Refresh Token

KakaoClient kakaoClient = KakaoClient.create();

try {
    KakaoRefreshTokenResponse response = kakaoClient.refreshToken()
            .clientId("YOUR_REST_API_KEY")
            .refreshToken("USER_REFRESH_TOKEN")
            .clientSecret("YOUR_CLIENT_SECRET") // Optional unless Client Secret is enabled
            .build()
            .execute();

    System.out.println("Refreshed Access Token: " + response.accessToken());
} catch (OAuthException e) {
    e.printStackTrace();
}

Kakao refresh token notes:

  • If Client Secret is enabled in the Kakao console, client_secret must be included in the refresh request.
  • id_token is only returned when the refresh token was originally issued with OpenID Connect.
  • refresh_token and refresh_token_expires_in are only returned when the current refresh token has less than one month remaining.
  • If Kakao returns an error such as KOE237, the library exposes it through OAuthResponseException#getErrorCode().

3. Get User Profile

KakaoClient kakaoClient = KakaoClient.create();

try {
    KakaoUserResponse user = kakaoClient.getUserInfo()
            .accessToken("ACCESS_TOKEN")
            .secureResource(false)
            .propertyKeys(KakaoPropertyKey.EMAIL)
            .build()
            .execute();

    System.out.println("Nickname: " + user.kakaoAccount().profile().nickname());
} catch (OAuthException e) {
    e.printStackTrace();
}

Naver Client

1. Exchange Code for Access Token

NaverClient naverClient = NaverClient.create();

try {
    NaverTokenResponse response = naverClient.getToken()
            .clientId("CLIENT_ID")
            .clientSecret("SECRET")
            .code("CODE")
            .state("STATE")
            .build()
            .execute();

    System.out.println("Access Token: " + response.accessToken());
} catch (OAuthException e) {
    e.printStackTrace();
}

2. Refresh Access Token with a Refresh Token

NaverClient naverClient = NaverClient.create();

try {
    NaverRefreshTokenResponse response = naverClient.refreshToken()
            .clientId("YOUR_CLIENT_ID")
            .clientSecret("YOUR_CLIENT_SECRET")
            .refreshToken("USER_REFRESH_TOKEN")
            .build()
            .execute();

    System.out.println("Refreshed Access Token: " + response.accessToken());
} catch (OAuthException e) {
    e.printStackTrace();
}

Naver refresh token notes:

  • Naver uses the same token endpoint for token issuance and token refresh, but the required parameters differ by grant_type.
  • The refresh token response follows the official refresh output fields and does not include refresh_token.
  • Naver may return HTTP 200 OK with error and error_description in the response body.
  • The library converts those responses into OAuthResponseException.

3. Get User Profile

NaverClient naverClient = NaverClient.create();

try {
    NaverUserResponse response = naverClient.getUserInfo()
            .accessToken("ACCESS_TOKEN")
            .build()
            .execute();
    
    System.out.println("Nickname: " + response.response().nickname());
} catch (OAuthException e) {
    e.printStackTrace();
}

Advanced Features

Selective Property Retrieval (Kakao Only)

You can request specific user properties to optimize the response size.

KakaoUserResponse user = kakaoClient.getUserInfo()
        .accessToken("ACCESS_TOKEN")
        .propertyKeys(KakaoPropertyKey.EMAIL, KakaoPropertyKey.PROFILE)
        .secureResource(true) // Return HTTPS URLs
        .build()
        .execute();

Error Handling

K-OAuth provides a detailed exception hierarchy to help you handle various failure scenarios.

  • OAuthValidationException: Thrown when mandatory parameters are missing before the request.

  • OAuthResponseException: Thrown when the OAuth provider returns a non-2xx response or a logical error (Naver's 200 OK error).

  • OAuthNetworkException: Thrown when network issues occur (timeouts, DNS failures).

  • OAuthParsingException: Thrown when a provider response cannot be parsed as expected JSON.

Validation and optional parameter notes:

  • Required values are validated at build() time and throw OAuthValidationException.
  • Optional parameters with null values are safely ignored.
try {
    // execute request...
} catch (OAuthResponseException e) {
    System.out.println("Status Code: " + e.getStatusCode());
    System.out.println("Error Code: " + e.getErrorCode());
    System.out.println("Message: " + e.getMessage());
} catch (OAuthException e) {
    // Handle other exceptions
}

Inspiration

Inspiration
Inspired by spotify-web-api-java.

Contributing

  • Issues and Pull Requests are always welcome.
  • Feel free to contribute, from small typo fixes to feature suggestions.

License

This project is licensed under the MIT License - see the LICENSE file for details.

About

A simple Java OAuth 2.0 library for Korean OAuth providers

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages