> For the complete documentation index, see [llms.txt](https://docs.hackle.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hackle.io/development-guide/sdk/user-identifier/client-user-identifier.md).

# 클라이언트 사용자 식별자

클라이언트에서는 두 가지 방법을 통해 사용자 식별자를 사용할 수 있습니다.

* SDK 내부적으로 관리하는 디바이스 식별자 사용
* 사용자 지정 식별자 사용

## SDK 내부적으로 관리하는 디바이스 식별자 사용

{% hint style="warning" %}
클라이언트 측 SDK에 한해 사용 가능합니다.
{% endhint %}

클라이언트 측 SDK는 디바이스의 식별자를 관리하는 기능을 포함하고 있습니다.\
따라서 사용자 식별자를 별도로 전달하지 않아도 사용자를 자동으로 식별할 수 있습니다.

JavaScript, Android, iOS의 경우 SDK가 관리하는 디바이스 식별자를 얻을 수 있으니 아래 예제 코드를 참고하시기 바랍니다.

```javascript
// 테스트 그룹 분배
const experimentKey = 42
const variation = hackleClient.variation(experimentKey)

// 사용자 이벤트 전송
hackleClient.track("purchase")

// 내부적으로 관리되는 디바이스 식별자 가져오기
const userId = Hackle.getUserId()
```

```java
// 테스트 그룹 분배
int experimentKey = 42;
Variation variation = hackleApp.variation(experimentKey);

// 사용자 이벤트 전송
hackleApp.track("purchase");

// 내부적으로 관리되는 디바이스 식별자 가져오기
String deviceId = hackleApp.getDeviceId();
```

```swift
// 테스트 그룹 분배
let variation = hackleApp.variation(experimentKey: 42)

// 사용자 이벤트 전송
hackleApp.track(eventKey: "purchase")

// 내부적으로 관리되는 디바이스 식별자 가져오기
let deviceId = hackleApp.deviceId
```

```javascript
<HackleProvider hackleClient={hackleClient}>
  <YourApp />
</HackleProvider>
```

## 사용자 지정 식별자 사용

SDK는 파라미터를 통해 받은 식별자를 통해 사용자를 식별합니다.\
전달하는 식별자는 직접 관리하는 Primary Key, 디바이스 식별자, 회원 아이디, 이메일, 해시값 등이 될 수 있습니다.

```javascript
// 테스트 그룹 분배
const experimentKey = 42;
const user = { userId: "ae2182e0" };
const variation = hackleClient.variation(experimentKey, user);

// 사용자 이벤트 전송
hackleClient.track("purchase", user);
```

```java
// 테스트 그룹 분배
long experimentKey = 42L;
String userId = "ae2182e0";
Variation variation = hackleApp.variation(experimentKey, userId);

// 사용자 이벤트 전송
hackleApp.track("purchase", userId);
```

```swift
// 테스트 그룹 분배
let variation = hackleApp.variation(experimentKey: 42, userId: "ae2182e0")

// 사용자 이벤트 전송
hackleApp.track(eventKey: "purchase", userId: "ae2182e0")
```

```javascript
const user = { 
    userId: "ae2182e0"
}

<HackleProvider hackleClient={hackleClient} user={user}>
  <YourApp />
```

### 사용자 지정 식별자 만들기 예시

로그인 사용자만을 대상으로 데이터가 필요한 경우에는 로그인 시 사용하는 회원 아이디나 이메일 주소 등을 식별자로 사용할 수 있습니다.

그러나 비로그인 사용자를 포함할 경우에는 앱, 기기 혹은 브라우저를 기반으로 구분할 수 있는 값을 활용하는 것을 권장하고 있습니다.\
(모바일 앱의 경우에는 UUID 혹은 ADID 값을, PC/Mobile 웹의 경우에는 쿠키 값)

아래에 쿠키를 기반으로 사용자 식별자를 생성하는 예시를 소개합니다.

```javascript
import Cookies from "js-cookie"
import uuid4 from "uuid4"
function getUserId() {
  const key = "PCID" // 원하는 이름을 입력
  const id = Cookies.get(key)
  if (id) {
    return id
  } else {
    const id = uuid4()
    const [top, second] = window.location.hostname.split(".").reverse()
    const domain = `.${second}.${top}`
    Cookies.set(key, id, { expires: 99999, domain: domain, path: "/" })
    return id
  }
}
```

```javascript
const app = require("express")()
const bodyParser = require("body-parser")
const cookieParser = require("cookie-parser")
const {v4: uuidv4} = require("uuid")

app.use(bodyParser.urlencoded({extended: false}))
app.use(cookieParser())
app.set("view engine", "ejs")
app.set("views", "views")

function extractDomain(hostname) {
    const DOMAIN_MATCH_REGEX = /[a-z0-9][a-z0-9-]+\.[a-z.]{2,6}$/i;
    const SIMPLE_DOMAIN_MATCH_REGEX = /[a-z0-9][a-z0-9-]*\.[a-z]+$/i;
    let domain_regex = DOMAIN_MATCH_REGEX;
    const parts = hostname.split(".");
    const tld = parts[parts.length - 1];
    if (tld.length > 4 || tld === "com" || tld === "org") {
        domain_regex = SIMPLE_DOMAIN_MATCH_REGEX;
    }
    const matches = hostname.match(domain_regex);
    return matches ? matches[0] : "";
}

app.use((req, res, next) => {
    const domain = extractDomain(req.headers.host)

    if (!req.cookies.deviceId) {
        const deviceId = uuidv4()
        res.cookie("deviceId", deviceId, {
            maxAge: 365 * 10 * 365 * 24 * 60 * 60,
            domain: domain,
            path: "/"
        })
        req.cookies.deviceId = deviceId
    }
    next()
});

app.get("/", (req, res) => {
    console.log(req.cookies.deviceId)
    res.render("index")
});

app.listen(3000, () => {
    console.log("App Start")
});
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.hackle.io/development-guide/sdk/user-identifier/client-user-identifier.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
