# URL 쿼리스트링 활용하기

URL 쿼리스트링이란 URL의 뒤에 입력 데이터를 함께 제공하는 데이터 전달 방법 입니다. \
**예시)** <mark style="color:purple;">`https://zep.us/play/{mapHashId}?{파라미터}={값}`</mark>

URL 쿼리스트링을 이용해 ZEP 스페이스 또는 ZEP Script로 데이터를 전달 할 수 있습니다.

## ZEP에서 사용 가능한 URL 쿼리스트링 파라미터

### 1. name

비로그인 유저 입장 시 닉네임을 name 파라미터로 전달한 값으로 설정할 수 있습니다.

* 예시: <mark style="color:purple;">`https://zep.us/play/{mapHashId}?name=학생A`</mark>

<div align="left"><figure><img src="/files/9IbSxCU4GNN3QuLILy93" alt=""><figcaption></figcaption></figure></div>

:warning: 게스트 유저 닉네임 설정 팝업 비활성화 설정을 해주세요!

<div align="left"><figure><img src="/files/WKAp1BiKjoLhbeY1Namw" alt=""><figcaption></figcaption></figure></div>

### 2. customData

ZEP Script player 객체에 데이터를 전달할 수 있습니다. \
SSO 토큰 정보 등의 유저 식별 정보를 ZEP Script로 전달하여 유저를 식별하는 등 화이트리스트 기능을 만드는 데 활용할 수 있습니다.

**예제 1** \
customData로 플레이어 정보를 받아 적용해보기 (노멀앱, 사이드바앱 권장)

⚡예제에서 사용한 URL

<mark style="color:purple;">`https://zep.us/play/{mapHashId}?customData={"name":"커스텀유저", "moveSpeed":150, "title":"커스텀타이틀"}`</mark>

```jsx
App.onJoinPlayer.Add(function (player) {
  // 전달받은 customData가 있는지 체크
	if (player.customData) {
		// customData를 오브젝트로 변환하여 사용
		let playerCustomData = JSON.parse(player.customData);
		if (playerCustomData.hasOwnProperty("name")) {
			player.name = playerCustomData["name"];
		}
		if (playerCustomData.hasOwnProperty("moveSpeed")) {
			player.moveSpeed = playerCustomData["moveSpeed"];
		}
		if (playerCustomData.hasOwnProperty("title")) {
			player.title = playerCustomData["title"];
		}
		App.sayToAll("커스텀 데이터를 적용했습니다");
		player.sendUpdated();
	}
  // 전달받은 customData가 없다면 메시지 출력 
  else {
		App.sayToAll("커스텀 데이터를 전달받지 못했습니다.");
	}
});
```

<div align="left"><figure><img src="/files/ahI5ZcLWbOuLFicUfvSU" alt=""><figcaption><p>customData를 전달받지 못한 경우</p></figcaption></figure> <figure><img src="/files/cCBsbRbYjChaIwf3eCdn" alt=""><figcaption><p>customData를 전달받아 적용한 경우</p></figcaption></figure></div>

**예제 2**

간단한 토큰기반 화이트리스트 기능 만들어보기 (노멀앱, 사이드바앱 권장)

{% file src="/files/fgE7LgU5HV5dQtW2hCcG" %}

✅ 브라우저 개발자 도구(F12)에서 다음과 같이 base64 암호화를 하여 토큰을 만들었습니다.

<div align="left"><figure><img src="/files/udltTGW7J7e84q5DT3dH" alt=""><figcaption></figcaption></figure></div>

⚡ 예제에서 사용한 URL

<mark style="color:purple;">`https://zep.us/play/{mapHashId}?customData=JTdCJTIydG9rZW4lMjIlM0ElMjIlRUMlOUMlQTAlRUMlQTAlODAxJTJGd2hpdGVMaXN0JTIyJTdE`</mark>

```jsx
App.onJoinPlayer.Add(function (player) {
	player.tag = {};
	if (player.customData) {
		let token = player.customData;
		// 위젯으로 토큰을 보내 복호화하기
		player.tag.widget = player.showWidget("main.html", "topleft", 1, 1);
		player.tag.widget.sendMessage({
			type: "decode",
			token: token,
		});
		player.tag.widget.onMessage.Add(function (player, data) {
			if (data.type == "decode") {
				let decodedToken = data.decodedToken;
				App.sayToAll(decodedToken);
				// 복호화 된 코드를 받은 후 오브젝트로 변환
				let playerData = JSON.parse(decodedToken);

				let playerName = playerData["token"].split("/")[0];
				let isTrusted = playerData["token"].split("/")[1];

				if (isTrusted == "whiteList") {
					player.name = playerName;
					player.title = "인증된유저";
					player.sendUpdated();
				}
				player.tag.widget.destroy();
				player.tag.widget = null;
			}
		});
	} else {
		App.sayToAll("커스텀 데이터를 전달받지 못했습니다.");
	}
});
```

```powershell
// 위젯에서 사용한 스크립트
window.addEventListener("message", function (e) {
  if (e.data.type == "decode") {
		// base64 토큰 복호화
    decodedToken = decodeURIComponent(atob(e.data.token));
    window.parent.postMessage({
      type: "decode",
      decodedToken: decodedToken
    }, "*")
  }
})
```

<div align="left"><figure><img src="/files/zzfUsjkqqv7CxGflMlN3" alt=""><figcaption><p>토큰으로 인증에 성공한 경우</p></figcaption></figure></div>


---

# Agent Instructions: 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:

```
GET https://docs-kr.zep.us/creator/reference/url.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
