Skip to content

Keycloak 시작하기

Import

ts
import { KeycloakClient } from '@jupiter/ts-monorepo';

const keycloak = new KeycloakClient({
    url: config.public.keycloakApiUrl,
    realm: config.public.keycloakRealm,
    clientId: config.public.keycloakClientId,
    clientSecret: config.public.keycloakClientSecret,
});
KeycloakClient Interface
ts
interface KeycloakOptions {
    url?: string;
    realm?: string;
    clientId?: string;
    clientSecret?: string;
    AUTH_INFO_KEY?: string;
    TOKEN_KEY?: string;
    notDeleteStorageKey?: string[];
};

requestToken(data: KeycloakRequestTokenData)

로그인 시 토큰을 요청하는 함수입니다.

파라미터

ts
interface KeycloakRequestTokenData {
    username: string;
    password: string;
    totp?: string;
    grantType?: string;
    scope?: string;
};

Exmple

ts
keycloak().requestToken({
    username: 'sjwiq200@jupiterstudio.co.kr',
    password: '12345',
}).then((res: any) => {
    console.dir(res);
}).catch((err: any) => {
    console.error(err);
});

성공 응답

localstroage의 AUTH_INFO_KEY 값과 TOKEN_KEY의 값을 설정함.

json
{
    "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ0Snd6WjBNRzlJOVdPREZiMWlRbVFoMHQwOFdwVXE3OV95dDRTdU1jcWNzIn0.eyJleHAiOjE3MTIyMTE2NDIsImlhdCI6MTcxMjIxMTM0MiwianRpIjoiZTg1NTljOGUtYmRmZC00MDFlLWJjYzUtODEyYjVlYzc0MGM5IiwiaXNzIjoiaHR0cHM6Ly9kZXYuYmlsbGJvYXJkLnRlYW0vcmVhbG1zL21pbGVzdG9uZS1kZXYiLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiYTgwZGVkOWYtNzc0Zi00MjU1LTg2ZDEtY2NlOWRiZGYxMTU3IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiaGFzdXJhLWtleWNsb2FrIiwic2Vzc2lvbl9zdGF0ZSI6IjQyZjVjZjEyLTgzZjUtNDJiOS05Y2M5LTI2ODEwNjg4YjhiNCIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiKiJdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsib2ZmbGluZV9hY2Nlc3MiLCJkZWZhdWx0LXJvbGVzLW1pbGVzdG9uZV9kZXYiLCJ1bWFfYXV0aG9yaXphdGlvbiJdfSwicmVzb3VyY2VfYWNjZXNzIjp7Imhhc3VyYS1rZXljbG9hayI6eyJyb2xlcyI6WyJjb21wYW55Il19LCJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIiwic2lkIjoiNDJmNWNmMTItODNmNS00MmI5LTljYzktMjY4MTA2ODhiOGI0IiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJodHRwczovL2hhc3VyYS5pby9qd3QvY2xhaW1zIjp7IngtaGFzdXJhLWRlZmF1bHQtcm9sZSI6InB1YmxpYyIsIngtaGFzdXJhLXVzZXItaWQiOiJhODBkZWQ5Zi03NzRmLTQyNTUtODZkMS1jY2U5ZGJkZjExNTciLCJ4LWhhc3VyYS1hbGxvd2VkLXJvbGVzIjpbImNvbXBhbnkiXX0sInByZWZlcnJlZF91c2VybmFtZSI6InNqd2lxMjAwQGp1cGl0ZXJzdHVkaW8uY28ua3IiLCJnaXZlbl9uYW1lIjoiIiwiZmFtaWx5X25hbWUiOiIifQ.gKlkHQyvsSsI8j3lltEQJ3IMwH01-KxGdxZLpuGojZuNvLZo3rBl4vLhhonLJnFFqv7wPboKF0UgJF_M3f884vvJq-tk9sI9D2lIi-GLbr8WaYad0Wq5Rhdg5GJeqSoHhV-GRl4xtHvYhKJOOshxTIL62xU6A_CSJFt_8UscPbeD-vsqltUU4e6p8QNGo9x8nzNcHEM3vqYiaE4sF6g37KpfEil3nM321pbN80W7CItx80Tj0Suf1IyMz2m0ifIE5Tc5iQP6Wac7dKAB1YfVw-G9NSxKXpaRJZV5KOBbrhToAoE0WGyQ9kfXdbeI5f0HrTlhQH-z4hOWz5cGbx9Gzg",
    "expires_in": 300,
    "refresh_expires_in": 1800,
    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI4MTQwNjAxYi03OGZiLTQ4NjItODEzZi1jMGY4NDNkNWE2NDYifQ.eyJleHAiOjE3MTIyMTMxNDIsImlhdCI6MTcxMjIxMTM0MiwianRpIjoiMDJhNmMwNGUtODRkNi00YTNmLWExNWUtMDEwNzE4OTAxMzAxIiwiaXNzIjoiaHR0cHM6Ly9kZXYuYmlsbGJvYXJkLnRlYW0vcmVhbG1zL21pbGVzdG9uZS1kZXYiLCJhdWQiOiJodHRwczovL2Rldi5iaWxsYm9hcmQudGVhbS9yZWFsbXMvbWlsZXN0b25lLWRldiIsInN1YiI6ImE4MGRlZDlmLTc3NGYtNDI1NS04NmQxLWNjZTlkYmRmMTE1NyIsInR5cCI6IlJlZnJlc2giLCJhenAiOiJoYXN1cmEta2V5Y2xvYWsiLCJzZXNzaW9uX3N0YXRlIjoiNDJmNWNmMTItODNmNS00MmI5LTljYzktMjY4MTA2ODhiOGI0Iiwic2NvcGUiOiJvcGVuaWQgcHJvZmlsZSBlbWFpbCIsInNpZCI6IjQyZjVjZjEyLTgzZjUtNDJiOS05Y2M5LTI2ODEwNjg4YjhiNCJ9.oGqSrlpR-OB2te67gCTMswQVqqsB2r1AKCUJ6C6g5Ho",
    "token_type": "Bearer",
    "id_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ0Snd6WjBNRzlJOVdPREZiMWlRbVFoMHQwOFdwVXE3OV95dDRTdU1jcWNzIn0.eyJleHAiOjE3MTIyMTE2NDIsImlhdCI6MTcxMjIxMTM0MiwiYXV0aF90aW1lIjowLCJqdGkiOiIxNzhhY2YyYS05MDhhLTQyNjEtOWZlZS1mNjJiNTdjNDhjMGIiLCJpc3MiOiJodHRwczovL2Rldi5iaWxsYm9hcmQudGVhbS9yZWFsbXMvbWlsZXN0b25lLWRldiIsImF1ZCI6Imhhc3VyYS1rZXljbG9hayIsInN1YiI6ImE4MGRlZDlmLTc3NGYtNDI1NS04NmQxLWNjZTlkYmRmMTE1NyIsInR5cCI6IklEIiwiYXpwIjoiaGFzdXJhLWtleWNsb2FrIiwic2Vzc2lvbl9zdGF0ZSI6IjQyZjVjZjEyLTgzZjUtNDJiOS05Y2M5LTI2ODEwNjg4YjhiNCIsImF0X2hhc2giOiJUTVFBcEh6TGpmeGwtMk9saTdjQjRRIiwiYWNyIjoiMSIsInNpZCI6IjQyZjVjZjEyLTgzZjUtNDJiOS05Y2M5LTI2ODEwNjg4YjhiNCIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwiaHR0cHM6Ly9oYXN1cmEuaW8vand0L2NsYWltcyI6eyJ4LWhhc3VyYS1kZWZhdWx0LXJvbGUiOiJwdWJsaWMiLCJ4LWhhc3VyYS11c2VyLWlkIjoiYTgwZGVkOWYtNzc0Zi00MjU1LTg2ZDEtY2NlOWRiZGYxMTU3IiwieC1oYXN1cmEtYWxsb3dlZC1yb2xlcyI6WyJjb21wYW55Il19LCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJzandpcTIwMEBqdXBpdGVyc3R1ZGlvLmNvLmtyIiwiZ2l2ZW5fbmFtZSI6IiIsImZhbWlseV9uYW1lIjoiIn0.PVFgq9oNKYqqsXE3YmCul20SqWtssPXfB1KrG4aBVDbRGE53ntIH4BbVB8eBbRP7_m69__CGCfyyjzI4DxMVS0INIPP3UXmpiJdbvrDtd1vgic_97DAGkkBZwNGfDSCaL67cOAkKZTZS0yUFbM_XOcw3oZ7xrZMtb1DPvH3gbKIhgyWOBJEED_RPOTYQxNvHAXZiT4c--Qcjal0Eu61FMQ6ELL2CbDP2WGy-4OUJ8V1u4RCI2met3HXHauOaczFFzQ2107JSsmmOMOIcHusrjsiNENw6Z15nGQebEvQjcKquRim5NixH-egOODT4kNR1wwmujAkE_xieS30DdkFfeA",
    "not-before-policy": 0,
    "session_state": "42f5cf12-83f5-42b9-9cc9-26810688b8b4",
    "scope": "openid profile email"
}

실패 응답

localstroage의 AUTH_INFO_KEY 값과 TOKEN_KEY의 값을 지움.

json
HTTP/1.1 401 Unauthorized
{
    "error":"invalid_grant",
    "error_description":"Invalid user credentials"
}

getToken()

로그인한 유저의 토큰을 가져오는 함수입니다.

Exmple

ts
keycloak().getToken();

성공 응답

localstroage에 저장된 TOKEN_KEY 값을 가져옴.

text
"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ0Snd6WjBNRzlJOVdPREZiMWlRbVFoMHQwOFdwVXE3OV95dDRTdU1jcWNzIn0.eyJleHAiOjE3MTIyMTE2NDIsImlhdCI6MTcxMjIxMTM0MiwianRpIjoiZTg1NTljOGUtYmRmZC00MDFlLWJjYzUtODEyYjVlYzc0MGM5IiwiaXNzIjoiaHR0cHM6Ly9kZXYuYmlsbGJvYXJkLnRlYW0vcmVhbG1zL21pbGVzdG9uZS1kZXYiLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiYTgwZGVkOWYtNzc0Zi00MjU1LTg2ZDEtY2NlOWRiZGYxMTU3IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiaGFzdXJhLWtleWNsb2FrIiwic2Vzc2lvbl9zdGF0ZSI6IjQyZjVjZjEyLTgzZjUtNDJiOS05Y2M5LTI2ODEwNjg4YjhiNCIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiKiJdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsib2ZmbGluZV9hY2Nlc3MiLCJkZWZhdWx0LXJvbGVzLW1pbGVzdG9uZV9kZXYiLCJ1bWFfYXV0aG9yaXphdGlvbiJdfSwicmVzb3VyY2VfYWNjZXNzIjp7Imhhc3VyYS1rZXljbG9hayI6eyJyb2xlcyI6WyJjb21wYW55Il19LCJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIiwic2lkIjoiNDJmNWNmMTItODNmNS00MmI5LTljYzktMjY4MTA2ODhiOGI0IiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJodHRwczovL2hhc3VyYS5pby9qd3QvY2xhaW1zIjp7IngtaGFzdXJhLWRlZmF1bHQtcm9sZSI6InB1YmxpYyIsIngtaGFzdXJhLXVzZXItaWQiOiJhODBkZWQ5Zi03NzRmLTQyNTUtODZkMS1jY2U5ZGJkZjExNTciLCJ4LWhhc3VyYS1hbGxvd2VkLXJvbGVzIjpbImNvbXBhbnkiXX0sInByZWZlcnJlZF91c2VybmFtZSI6InNqd2lxMjAwQGp1cGl0ZXJzdHVkaW8uY28ua3IiLCJnaXZlbl9uYW1lIjoiIiwiZmFtaWx5X25hbWUiOiIifQ.gKlkHQyvsSsI8j3lltEQJ3IMwH01-KxGdxZLpuGojZuNvLZo3rBl4vLhhonLJnFFqv7wPboKF0UgJF_M3f884vvJq-tk9sI9D2lIi-GLbr8WaYad0Wq5Rhdg5GJeqSoHhV-GRl4xtHvYhKJOOshxTIL62xU6A_CSJFt_8UscPbeD-vsqltUU4e6p8QNGo9x8nzNcHEM3vqYiaE4sF6g37KpfEil3nM321pbN80W7CItx80Tj0Suf1IyMz2m0ifIE5Tc5iQP6Wac7dKAB1YfVw-G9NSxKXpaRJZV5KOBbrhToAoE0WGyQ9kfXdbeI5f0HrTlhQH-z4hOWz5cGbx9Gzg"

getUserInfo()

로그인한 유저의 정보를 가져오는 함수입니다.

Exmple

ts
keycloak().getUserInfo();

성공 응답

localstroage에 저장된 TOKEN_KEY 값을 복호화하여 유저 정보를 가져옴.

json
{
    "exp": 1717123827,
    "iat": 1717122027,
    "jti": "bf283bef-ee06-4c79-822b-0198b651defa",
    "iss": "https://keycloak.exmple.me/auth/realms/exmple",
    "aud": "account",
    "sub": "45265147-4436-44f7-bf99-b8ea0722e7a9",
    "typ": "Bearer",
    "azp": "hasura-keycloak",
    "session_state": "d2cca2e5-6638-4379-acc3-1cde304bff5e",
    "acr": "1",
    "allowed-origins": [
        "*"
    ],
    "realm_access": {
        "roles": [
            "offline_access",
            "uma_authorization"
        ]
    },
    "resource_access": {
        "hasura-keycloak": {
            "roles": [
                "admin",
                "user"
            ]
        },
        "account": {
            "roles": [
                "manage-account",
                "manage-account-links",
                "view-profile"
            ]
        }
    },
    "scope": "openid email profile",
    "sid": "d2cca2e5-6638-4379-acc3-1cde304bff5e",
    "email_verified": false,
    "https://hasura.io/jwt/claims": {
        "x-hasura-default-role": "public",
        "x-hasura-user-id": "45265147-4436-44f7-bf99-b8ea0722e7a9",
        "x-hasura-allowed-roles": [
            "admin",
            "user"
        ]
    },
    "preferred_username": "chogeonhee",
    "given_name": "",
    "family_name": ""
}

getUserRoles()

로그인한 유저의 Role 목록을 가져오는 함수입니다.

Exmple

ts
keycloak().getUserRoles();

성공 응답

localstroage에 저장된 TOKEN_KEY 값을 복호화하여 유저 Role 목록을 가져옴.

json
[
  "admin",
  "user"
]

getUserUUID()

로그인한 유저의 UUID를 가져오는 함수입니다.

Exmple

ts
keycloak().getUserUUID();

성공 응답

localstroage에 저장된 TOKEN_KEY 값을 복호화하여 유저의 UUID 값을 가져옴.

text
"45265147-4436-44f7-bf99-b8ea0722e7a9"

logout()

로그아웃 하는 함수입니다. localstroage에 저장된 로그인 정보들을 삭제합니다.

Exmple

ts
keycloak().logout();

refreshToken()

로그인 한 유저의 토근을 재발급하는 함수입니다.

Exmple

ts
keycloak().refreshToken().then((res: any) => {
    console.dir(res);
}).catch((err: any) => {
    console.error(err);
});

성공 응답

localstroage의 AUTH_INFO_KEY 값과 TOKEN_KEY의 값을 설정함.

text
true

실패 응답

text
false

isLoggedIn()

로그인 한 유저의 유효한 로그인 정보를 체크하는 함수입니다. 토큰의 유효시간이 3분 미만일 경우 토큰을 재발급합니다.

Exmple

ts
keycloak().isLoggedIn();

성공 응답

text
true

실패 응답

text
false