# 로그인

위핀 RESTful API는 아래와 같이 인증이 필요합니다.

### 토큰 <a href="#token" id="token"></a>

위핀 RESTful API 요청 시, Token을 추가하여 인증을 수행해야 합니다. 위핀 RESTful API의 토큰은 JWT 토큰 포맷으로 생성 됩니다. 기본 JWT 방식의 인증(보안) 강화 방식인 **Access Token & Refresh Token** 인증 방식을 채택해서 사용합니다.

{% hint style="info" %}
Access Token은 발급 후  12시간 후 만료됩니다. Refresh Token은 7일 동안 유효하며, 이를 통해 새로운 Access Token을 발급 받을 수 있습니다.
{% endhint %}

[로그인](#login) 요청을 보내면 Response에 토큰이 반환됩니다. 여기에는 `accessToken`과 `refreshToken` 토큰이 포함되어 있습니다. 자세한 토큰 발급 절차는 아래와 같습니다.

1. [로그인](#login) 과정에서 **Access Token**과 **Refresh Token** 을 발급 받습니다.
2. 이후 API Request를 보내기 전에 토큰의 유효성을 검증합니다.&#x20;
   * **Access Token**과 **Refresh Token** 모두 만료된 경우: 에러 발생. 다시 로그인을 수행해서 새로운 **Access Token**과 **Refresh Token**을 발급 받습니다.
   * **Access Token**은 만료되었지만 **Refresh Token**은 유효한 경우:  [토큰 재발급 받기](#token-reissue)를 통해서 **Refresh Token**을 검증하여 **Access Token** 을 재발급 받습니다.
   * **Access Token**은 유효하지만 **Refresh Token**은 만료된 경우: 다시 [로그인](#login)을 수행하여 새로운 **Access Token**과 **Refresh Token**을 발급 받습니다.
   * **Access Token**과 **Refresh Token** 모두 유효한 경우: 정상적으로 Request를 보낼 수 있습니다.
3. 위핀 RESTful API를 사용하는 클라이언트 어플리케이션은 토큰의 유효 시간을 확인 후, 토큰이 유효한 경우에만 Request를 수행합니다.&#x20;
4. 또는 토큰 유효성 검증 없이 API Request를 전송하고, HTTP Status 코드 `401`을 받으면 토큰을 재발급 받습니다.

#### Request 헤더 <a href="#request-header" id="request-header"></a>

위핀 SDK API의 Request 헤더 값입니다.

<table><thead><tr><th width="182">Name</th><th width="181">Value</th><th>Description</th></tr></thead><tbody><tr><td>X-API-KEY</td><td>${APP_KEY}</td><td>앱 등록 시 할당 받은 App Key 값</td></tr><tr><td>X-API-DOMAIN</td><td>${APP_DOMAIN}</td><td>앱 생성 시 등록한 기본 도메인 또는 패키지 이름 또는 bundle ID</td></tr><tr><td>Authorization</td><td>Bearer {token}</td><td>{token}은 위핀 로그인 후 받은 Access Token</td></tr><tr><td>X-SDK-TYPE</td><td>{platform}_rest_api</td><td><p>RESTful API를 사용하는 플랫폼 </p><p>&#x3C;android | ios | web> . e.g) web_res_api</p></td></tr><tr><td>Content-Type</td><td>application/json</td><td></td></tr></tbody></table>

#### Status Code

<table><thead><tr><th width="260">Code</th><th>Description</th></tr></thead><tbody><tr><td>200</td><td>성공. Response에 JSON 객체를 포함.</td></tr><tr><td>400</td><td>잘못된 데이터 전송</td></tr><tr><td>401</td><td>토큰 만료</td></tr><tr><td>403</td><td>App Key 오류</td></tr><tr><td>404</td><td>Not Found</td></tr><tr><td>500</td><td>서버 Internal 오류</td></tr></tbody></table>

#### Error Response

<table><thead><tr><th width="162">Name</th><th width="180">Type</th><th>Description</th></tr></thead><tbody><tr><td>message</td><td>String</td><td>에러 메시지</td></tr><tr><td>code</td><td>Integer</td><td>에러 코드 값</td></tr><tr><td>data</td><td>Object</td><td>에러 상세 데이터</td></tr></tbody></table>

***

### 앱 정보 확인하기 <a href="#check-app-information" id="check-app-information"></a>

앱 등록 후 발급 받은 App Key 검증 및 등록한 앱에 대한 정보가 맞는지 확인합니다.

```http
GET /v1/app/info HTTP/1.1
Host: sdk.wepin.io
X-API-KEY: ${APP_KEY}
X-API-DOMAIN: {APP_DOMAIN}
X-SDK-TYPE: {platform}_rest_api
Content-Type: application/json
```

#### Request

**Parameter**

<table><thead><tr><th width="148">Name</th><th width="104">Type</th><th width="377">Description</th><th>Required</th></tr></thead><tbody><tr><td>platform</td><td>Integer</td><td><code>1</code>: web<br><code>2</code>: android<br><code>3</code> : ios</td><td>O</td></tr><tr><td>withNetwork</td><td>Boolean</td><td><code>true</code>: 워크스페이스에 등록한 앱이 사용할 네트워크 정보를 반환함. <br><code>false</code>: 워크스페이스에 등록한 앱이 사용할 네트워크 정보 반환 하지 않음. default 값.</td><td>X</td></tr></tbody></table>

#### Response

**Success Response**

| Name    | Type    | Description                                                   |
| ------- | ------- | ------------------------------------------------------------- |
| stage   | Integer | <p><code>1</code>: development<br><code>2</code>: product</p> |
| appInfo | Object  | 앱 정보(`appinfo`)                                               |

* `appInfo`
  * `id` : App ID
  * `assets` *array of object*
    * `coinId` *integer*
      * 앱에서 사용하는 네트워크 코인 ID
    * `tokens` *integer\[]*
      * 앱에서 사용하는 FT(Fungible Token) ID List

***

### 로그인 <a href="#login" id="login"></a>

위핀 지갑을 사용하기 위해서 로그인을 해야 합니다. 위핀은 Firebase를 이용한 소셜 로그인 및 이메일 로그인을 지원하고 있습니다. 위핀에서 지원하는 소셜 로그인 목록을 확인하려면 [**소셜 로그인 인증 프로바이더 페이지**](https://docs.wepin.io/login/social-login-auth-provider)를 참고하세요.

{% hint style="info" %}
위핀은 다양한 개발 환경에 맞게 로그인 라이브러리를 제공하고 있습니다. 플랫폼에 따른 로그인 라이브러리 목록은 [API의 개요 페이지](https://docs.wepin.io/restful-api/overview)를 참고하세요.&#x20;
{% endhint %}

Firebase 로그인 결과로 얻은 토큰을 이용하여 위핀 로그인을 수행합니다.

```http
POST /v1/user/login HTTP/1.1
Host: sdk.wepin.io
X-API-KEY: ${APP_KEY}
X-API-DOMAIN: {APP_DOMAIN}
X-SDK-TYPE: {platform}_rest_api
Content-Type: application/json

{
	"idToken": "abc12..22"
}
```

#### Request

**Parameter**

<table><thead><tr><th width="151">Name</th><th width="115">Type</th><th width="342">Description</th><th>Required</th></tr></thead><tbody><tr><td>idToken</td><td>String</td><td>(위핀 로그인 라이브러리를 이용하여) Firebase 로그인 결과 얻은 토큰 값</td><td>O</td></tr></tbody></table>

#### **Response**

<table><thead><tr><th width="186">Name</th><th width="173">Type</th><th>Description</th></tr></thead><tbody><tr><td>loginStatus</td><td>String</td><td><code>pinRequired</code>: 위핀 최초 로그인인 경우, 위핀 회원 가입과 동시에 새로운 지갑을 생성해야 합니다. 따라서 지갑 생성에 필요한 사용자 PIN 등록이 필요합니다.<br><code>registerRequired</code>: 사용자가 이미 위핀 지갑을 가지고 있지만 해당 앱을 처음 사용하는 경우, 사용자의 위핀지갑에 해당 앱 등록을 해야 합니다. 따라서 기존에 생성한 사용자 지갑의 사용자 PIN 인증이 필요합니다.<br><code>complete</code>: 사용자 로그인이 완료 되었음을 의미합니다.</td></tr><tr><td>walletId</td><td>string (optional)</td><td>사용자 지갑 ID. 지갑이 이미 생성되어 있는 경우(loginStatus 가 <code>registerRequired</code>, <code>complete</code> 인 경우) walletId 가 반환됩니다.</td></tr><tr><td>token</td><td>Object</td><td>위핀에 정상적으로 로그인이 완료되면 <code>token</code> 이 반환됩니다.</td></tr><tr><td>userInfo</td><td>UserInfo (Object)</td><td>로그인 완료된 경우의 사용자 정보입니다. <code>loginStatus</code>가 <code>complete</code> 인 경우에만 반환 됩니다. (<code>userInfo)</code></td></tr></tbody></table>

* `token`
  * `access` *String*
    * Access Token (인코딩 된 JWT 토큰)
  * `refresh` *String*
    * Refresh Token (인코딩 된 JWT 토큰)

* `userInfo`
  * `userId` *String*
    * 사용자 Id
  * `email` *String*
    * 사용자의 e-mail
  * `name` *String*
    * 사용자의 이름
  * `locale` *String*
    * 사용자가 설정해 놓은 언어
  * `currency` *String*
    * 사용자가 설정해 놓은 통화
  * `lastAccessDevice` *String*
    * 마지막 접속 기기
  * `lastSessionIp` *String*
    * 마지막 접속 IP
  * `userJoinStage` *Integer*
    * 사용자 가입 단계. (REST API를 직접 호출 하는 경우 사용하지 않음)
    * `3`: 가입 완료
  * `profileImage` *String*
    * 사용자의 프로필 이미지 URL
  * `userState` *Integer*
    * 사용자 상태
    * `1`: active
    * `2`: deleted
  * `user2FA` *Integer*
    * 2FA 활성화 여부
    * `0` : 생성은 됐지만 인증이 되지 않은 상태 - 2FA 사용 불가
    * `1` : 등록 완료 상태
    * `2`: 2FA 복구 코드 검증 완료된 상태

*Example*

```json
{
    "loginStatus": "complete",
    "userInfo": {
        "email": "sample-user@wepin.io",
        "name": "Sample User Name",
        "locale": "ko",
        "currency": "KRW",
        "lastAccessDevice": "Windows 10 Chrome 112.0.0.0",
        "lastSessionIP": "xxx.xxx.xxx.xxx",
        "userJoinStage": 3,
        "profileImage": "<https://profile.wepin.io/user-1>",
        "userState": 1,
        "use2FA": 2
    }
}
```

***

### 로그아웃 <a href="#logout" id="logout"></a>

사용자 로그아웃을 수행합니다. Firebase 로그아웃과 위핀 로그인 라이브러리의 logout 함수와 함께 사용됩니다.

```http
POST /v1/user/{userId}/logout HTTP/1.1
Host: sdk.wepin.io
X-API-KEY: ${APP_KEY}
X-API-DOMAIN: {APP_DOMAIN}
X-SDK-TYPE: {platform}_rest_api
Content-Type: application/json
Authorization: Bearer ${access_token}
```

#### Request

**Parameter**

<table><thead><tr><th width="149">Name</th><th width="103">Type</th><th width="364">Description</th><th>Required</th></tr></thead><tbody><tr><td>userId</td><td>String</td><td><a href="#undefined-1">로그인</a> 과정에서 받은 <code>userInfo</code>의 userId.</td><td>O</td></tr></tbody></table>

#### Response

**Success Response**

비어 있는 Object를 반환 합니다.

```json
{}
```

***

### 토큰 재발급 받기 <a href="#token-reissuance" id="token-reissuance"></a>

발급 받은 **Access Token**이 만료되고 **Refresh Token**은 유효한 경우에, 새로운 **Access Token**을 재발급 받아야 합니다.

```http
GET /v1/user/access-token?userId={userId}&refresh_token={refresh_token} HTTP/1.1
Host: sdk.wepin.io
X-API-KEY: ${APP_KEY}
X-API-DOMAIN: {APP_DOMAIN}
X-SDK-TYPE: {platform}_rest_api
Content-Type: application/json
Authorization: Bearer ${access_token}
```

#### Request

**Parameter**

<table data-header-hidden><thead><tr><th width="173"></th><th width="118"></th><th width="361"></th><th></th></tr></thead><tbody><tr><td><strong>Name</strong></td><td><strong>Type</strong></td><td><strong>Description</strong></td><td><strong>Required</strong></td></tr><tr><td>userId</td><td>String</td><td>로그인 과정에서 받은 <code>userInfo</code>의 userId.</td><td>O</td></tr><tr><td>refresh_token</td><td>String</td><td>로그인 과정에서 받은 Refresh Token. (<code>token</code>)</td><td>O</td></tr></tbody></table>

#### Response

| Name  | Type   | Description      |
| ----- | ------ | ---------------- |
| token | String | 새로운 Access Token |

***

### 이용 약관 동의하기 <a href="#agreeing-to-terms-of-service" id="agreeing-to-terms-of-service"></a>

위핀 지갑 로그인과 동시에 사용자는 지갑 이용 약관에 동의 해야 합니다.  [로그인](#login)에 성공한 후 이용 약관 동의 여부를 위핀 백엔드 서버에 업데이트 합니다.

```http
PATCH /v1/user/{userId}/terms-accepted HTTP/1.1
Host: sdk.wepin.io
X-API-KEY: ${APP_KEY}
X-API-DOMAIN: {APP_DOMAIN}
X-SDK-TYPE: {platform}_rest_api
Content-Type: application/json
Authorization: Bearer ${access_token}

{
	"termsAccepted": {
		"termsOfService": true 
		"privacyPolicy": true,
	}
}
```

#### Request

**Parameter**

<table><thead><tr><th width="163">Name</th><th width="95">Type</th><th width="395">Description</th><th>Required</th></tr></thead><tbody><tr><td>termsAccepted</td><td>Object</td><td>사용자가 동의한 약관 입니다. <br>약관의 종류가 늘어나는 경우 property가 추가됩니다.<br>각 property의 값이 true로 변경되면 이후에 다시 false가 될 수 없습니다.</td><td>O</td></tr></tbody></table>

* `termsAccepted`
  * `termsOfService` *Boolean*
    * 서비스 이용 약관 동의 여부
  * `privacyPolicy` *Boolean*
    * 개인정보 처리 방침 동의 여부
* 위핀 지갑 서비스 약관
  * 이용약관: [국문](https://delivery.wepin.io/service/terms/ko.html) | [영문](https://delivery.wepin.io/service/terms/en.html)
  * 개인정보처리방침: [국문](https://delivery.wepin.io/service/privacy/ko.html) | [영문](https://delivery.wepin.io/service/privacy/en.html)

#### Response

Request의 body와 동일합니다.

<table><thead><tr><th width="162">Name</th><th width="89">Type</th><th>Description</th></tr></thead><tbody><tr><td>termsAccepted</td><td>Object</td><td>사용자가 동의한 약관 입니다.<br>약관의 종류가 늘어나는 경우 property가 추가됩니다.<br>각 property의 값이 true로 변경되면 이후에 다시 false가 될 수 없습니다.</td></tr></tbody></table>

## 이용 약관 동의 여부 가져오기 <a href="#get-terms-of-service-agreement-status" id="get-terms-of-service-agreement-status"></a>

사용자의 이용 약관 동의 여부를 가져 올 수 있습니다.

```http
GET /v1/terms-accepted HTTP/1.1
Host: sdk.wepin.io
X-API-KEY: ${APP_KEY}
X-API-DOMAIN: {APP_DOMAIN}
X-SDK-TYPE: {platform}_rest_api
Content-Type: application/json
Authorization: Bearer ${access_token}
```

#### Request

**Parameter**

#### Response

<table><thead><tr><th width="161">Name</th><th width="89">Type</th><th width="415">Description</th><th>Required</th></tr></thead><tbody><tr><td>termsAccepted</td><td>Object</td><td>사용자가 동의한 약관 입니다.<br>약관의 종류가 늘어나는 경우 property가 추가가 됩니다.<br>각 property의 값이 true로 변경되면 이후에 다시 false가 될 수 없습니다.</td><td>O</td></tr></tbody></table>
