---
# System prepended metadata

title: App登入、登出

---

# App登入、登出

## 取用token、IV
Request:
```javascript
GET /login/secret
```

Response: 
```javascript
{
    "httpCode": 200,
    "result": {
        "data": {
            "IV": "wicckmuh@wistron",
            "Key": "wicckmuh.wistron"
        }
    }
}
```

## App 登入
Request:
    
    POST /login/app

body:

```javascript
{
    "countryCode": "+886",
    "account": "A184407779",
    "deviceToken": "exJ9GIMMHuI:APA91bGMV77g0pbqg3tSuJ2cbYU7mEs8xA-SbyYN4NsJAY52qJkA2rTtKqifIqzUfDM4mP7edxqC4irIDAcP-IwlLG7gdEt1-ydOAi0shKX9AV7rqKgPiaoJKCx27CMRxoiNQVH7MiAc",
    "deviceType": "ANDROID_APP",
    "loginType": "kmuh",
    "password": "3yrOv6Rh10zk8zAxmxNtqw==\n",
    "clearDuplicateLogin": true,
    "eulaId": "5b323376-2bdc-4741-a787-d538db86fbff"
}
```

錯誤代碼

    100(成功)/101(找不到使用者)/102(角色錯誤)/103(密碼錯誤)/104(重複登入)/105(未同意隱私權)/ 106(首次登入)
    

res:  e.g. Code = 106 (第一次登入) 

```javascript
{
    "httpCode": 200,
    "result": {
        "data": {
            "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJXaWNjS01VSCIsImFjY291bnRJZCI6IjJhZTI0MWI4LWQ1ZmMtNGNmNy1hZDJkLThlMzE0YmUzZjEyYiIsImFyZWFDb2RlIjoiODU4YjdmYmItM2JhMC00ZDQ5LTk4ODItYzg5M2ExZWYwN2RjIiwibG9naW5UeXBlIjoia211aCIsImRpc3BsYXlOYW1lIjoi5aSp56u66byg6LuK6LuKIiwic3VybmFtZSI6IuWkqeeruum8oOi7iui7iiIsImlzcyI6Ildpc3Ryb24gU1dQQyIsImhvdXNlaG9sZE1lbWJlcklkIjoiNjA3ZjFiMDItZGQzNi00OWEyLWE2MGUtZjEwOWVkMjhiNWVkIiwidGVuYW50SWQiOiI4NThiN2ZiYi0zYmEwLTRkNDktOTg4Mi1jODkzYTFlZjA3ZGMiLCJyb2xlVHlwZSI6IkdFTkVSQUxfUFVCTElDIiwidXNlcklkIjoiRTEzNjQyNzY5OCIsImp0aSI6Ijg1ZjVjYjAzLTdiYjktNGY2MC05ZmYwLWI5Zjk5YmI0Y2MyYiJ9.2sYi53jwlBrBK33mxLHONN_QhwM6CnMNl2tGyQ3b1mo",
            "code": 106,
            "expireDate": "Fri Mar 05 16:28:46 CST 2021"
        }
    }
}
```


## App登出
* 登入不需要token，但登出需要token。
Request:
```url=
POST /user/logout/app
```

header
```javascript
{
    "header": "{{token}}" 
}
```

Response:
```javascript
{
    "httpCode": 200,
    "result": {
        "data": {
            "isSuccess": true
        }
    }
}
```

## 變更密碼
* 變更密碼必須有token，亦即必須在登入狀態

Request:
```javascript
POST /generalPublic/changePassword
```

header
```javascript
{
    "header": "{{token}}" 
}
```

Payload:
```javascript
{
    "countryCode": "+886",
    "phone":"E124692461",
    "password": "LoM7aCNhoIHkcO+eoRUlKA=="
}
```

Response:
```javascript
{
    "httpCode": 200,
    "result": {
        "data": "true"
    }
}
```

ErrorMsg:
* A. 密碼重複未變更 PASSWORD_SAME_AS_OLD
```javascript
{
    "errorMsg": "SERVICE_ERROR.PASSWORD_SAME_AS_OLD",
    "httpCode": 422
}
```
* B. 舊密碼錯誤
```javascript
{
    "errorMsg":"SERVICE_ERROR.PASSWORD_ERROR",
    "httpCode": 422
}
```

## 重置密碼(Deprecated)
* 已棄用, 改使用忘記密碼流程
* ~~重置密碼走驗證信流程，亦即不必在登入狀態（沒token）~~
* ~~重置密碼改成以生日(ｙｙｙｙＭＭｄｄ)當密碼，登入時一樣要要求變更密碼一次~~

Request:
```javascript
{
    "account": "C188256154",
    "telephone": "09123456789"
}
```

Response: 
```javascript
{
    "httpCode": 200,
    "result": {
        "data": {
            "account": "C188256154",
            "password": "20210217", // 暫時會給，以後加入簡訊流程建議拿掉
            "clearDuplicateLogin": false,
            "telephone": "09123456789"
        }
    }
}
```

ErrorMsg:
* 帳號不存在或者電話不相符
```javascript
{
    "errorMsg": "SERVICE_ERROR.ACCOUNT_NOT_EXISTS",
    "httpCode": 422
}
```

## App 註冊帳號
* 不必有token

Request:
```javascript
POST /account/register
```

Attribute | Type | IsRequired | Remark
-|-|-|-
idNo   | String | N | 身分證字號
birthDate | String | Y | 生日(yyyy-MM-dd)
name | String | Y | 姓名
countryCode | String | Y | 電話國碼, e.g.台灣為+886
telephone | String | Y | 電話
bodyHeight | number | Y | 身高
gender | int | Y | 性別 1:男性/2:女性
address | String | N | 地址
bloodType | String | N | 血型(O/AB/A/B)
email | String | N | email
otp | String | Y | otp, 6位數字
password | String | Y | 密碼, 需加密
waist | int | N | 腰圍
hips  | int | N | 臀圍

Payload:
```javascript
{
    "idNo": "A120232858",
    "birthDate": "2021-02-17",
    "name": "陳三洋",
    "countryCode": "+886",
    "telephone": "0987654321",
    "bodyHeight": 166,
    "gender": 1,
    "address": "高雄市鹽埕區大勇路100號",
    "bloodType": "O",
    "email": "123@gmail.com",
    "otp": "123456",
    "password": "LoM7aCNhoIHkcO+eoRUlKA==",
    "waist": 90,
    "hips": 110
}
```

Response:
```javascript
{
    "httpCode": 200,
    "result": {
        "data": {
            "accountId": "a72ccbc3-947d-467e-914e-3928dad3270e",
            "householdMemberId": "153c671d-29d4-48f2-8ef0-a4b8598dd5d2"
        }
    }
}
```

ErrorMsg:

* 已經存在的手機號碼(同手機號不同名稱時會將舊帳號封存,封存舊帳號尚未完成,會先拋此ErrorMsg)
```javascript
{
    "errorMsg": "SERVICE_ERROR.ACCOUNT_TELEPHONE_DUPLICATE",
    "httpCode": 422
}
```

* OTP驗證失敗
```javascript
{
    "errorMsg": "SERVICE_ERROR.OTP_VALIDATE_FAIL",
    "httpCode": 422
}
```

## App 解除帳號

```javascript
POST /account/unregister
```

### Request
 欄位 | 型態  | 必填 | 長度限制 | 預設 | 說明 
 ---|---|---|---|---|---


### Response
 欄位 | 型態 | 說明 
 ---  | --- | ---
 data|int|解除帳號數量
```javascript
{
    "httpCode": 200,
    "result": {
        "data": 1
    }
}
```



## 產生OTP
* 不需token

Request:
```URL
POST /otp/generate
```

Body:
欄位 | 型態 | 必填 | 說明
-|-|-|-
countryCode | String | Y | 電話國碼, e.g.台灣為+886
phone | String | Y | 手機號碼(台灣手機號碼格式09.....)
otpType | String | Y | OTP類型; REGISTER: 註冊, FORGOT_PW: 忘記密碼

```javascript
{
    "countryCode": "+886",
    "phone":"0987654321",
    "otpType":"REGISTER"
}
```

Response: 
欄位 | 型態 | 說明
-|-|-
id | String | otp記錄 id
otp | String | otp, 6位數字, 測試用時顯示, 實際介接SMS發送時不會顯示此欄位

```javascript
{
    "httpCode": 200,
    "result": {
        "data": {
            "id": "a72ccbc3-947d-467e-914e-3928dad3270e",
            "otp": "123456"
        }
    }
}
```

ErrorMsg:
```javascript
// 超過重送次數
{
    "errorMsg": "SERVICE_ERROR.OTP_EXCEED_RESEND_TIMES",
    "httpCode": 422
}

// OTP已過期
{
    "errorMsg": "SERVICE_ERROR.OTP_EXPIRED",
    "httpCode": 422
}

// OTP驗證失敗
{
    "errorMsg": "SERVICE_ERROR.OTP_VALIDATE_FAIL",
    "httpCode": 422
}
```

## 重送OTP
* 不需token

Request:
```URL
POST /otp/resend
```

Body:
欄位 | 型態 | 必填 | 說明
-|-|-|-
countryCode | String | Y | 電話國碼, e.g.台灣為+886
phone | String | Y | 手機號碼(台灣手機號碼格式09.....)
otpType | String | Y | OTP類型; REGISTER: 註冊, FORGOT_PW: 忘記密碼

```javascript
{
    "countryCode": "+886",
    "phone":"0987654321",
    "otpType":"REGISTER"
}
```

Response: 
欄位 | 型態 | 說明
-|-|-
id | String | otp記錄 id
otp | String | otp, 6位數字, 測試用時顯示, 實際介接SMS發送時不會顯示此欄位


```javascript
{
    "httpCode": 200,
    "result": {
        "data": {
            "id": "a72ccbc3-947d-467e-914e-3928dad3270e",
            "otp": "123456"
        }
    }
}
```

ErrorMsg:
```javascript
// 超過重送次數
{
    "errorMsg": "SERVICE_ERROR.OTP_EXCEED_RESEND_TIMES",
    "httpCode": 422
}

// OTP已過期
{
    "errorMsg": "SERVICE_ERROR.OTP_EXPIRED",
    "httpCode": 422
}

// OTP驗證失敗
{
    "errorMsg": "SERVICE_ERROR.OTP_VALIDATE_FAIL",
    "httpCode": 422
}
```


## 驗證OTP
* 不需token

Request:
```URL
POST /otp/validate
```

Body:
欄位 | 型態 | 必填 | 說明
-|-|-|-
countryCode | String | Y | 電話國碼, e.g.台灣為+886
phone | String | Y | 手機號碼(台灣手機號碼格式09.....)
otpType | String | Y | OTP類型; REGISTER: 註冊, FORGOT_PW: 忘記密碼
otp | String | Y | otp, 6位數字

```javascript
{
    "countryCode": "+886",
    "phone":"0987654321",
    "otpType":"FORGOT_PW"
    "otp": "123456"
}
```

Response: 
欄位 | 型態 | 說明
-|-|-
id | String | otp記錄 id

```javascript
{
    "httpCode": 200,
    "result": {
        "data": {
            "id": "a72ccbc3-947d-467e-914e-3928dad3270e"
        }
    }
}
```

ErrorMsg:
```javascript
// OTP驗證失敗
{
    "errorMsg": "SERVICE_ERROR.OTP_VALIDATE_FAIL",
    "httpCode": 422
}
```


## 客服取OTP
* 不需token
* 客服取OTP的token會每日定時更換, 可以先詢問系統管理者

Request:
```URL
POST /otp/supervisor-call
```

Body:
欄位 | 型態 | 必填 | 說明
-|-|-|-
countryCode | String | Y | 電話國碼, e.g.台灣為+886
phone | String | Y | 手機號碼(台灣手機號碼格式09.....)
otpType | String | Y | OTP類型; REGISTER: 註冊, FORGOT_PW: 忘記密碼
supervisorToken | String | Y | 客服取OTP的專用token, 為6碼數字

```javascript
{
    "countryCode": "+886",
    "phone":"0987654321",
    "otpType":"REGISTER",
    "supervisorToken": "123456"
}
```

Response: 
欄位 | 型態 | 說明
-|-|-
id | String | otp記錄 id
otp | String | otp, 6位數字, 測試用時顯示, 實際介接SMS發送時不會顯示此欄位
expireTime | Date | otp到期時間

```javascript
{
    "httpCode": 200,
    "result": {
        "data": {
            "id": "a72ccbc3-947d-467e-914e-3928dad3270e",
            "otp": "123456",
            "expiredTime": 1639992592000
        }
    }
}
```

ErrorMsg:
```javascript
// 使用的supervisorToken驗證失敗
{
    "errorMsg": "SERVICE_ERROR.OTP_SUPERVISOR_FAIL",
    "httpCode": 422
}

// 無此電話的OTP記錄
{
    "errorMsg": "API_ERROR.NO_DATA",
    "httpCode": 400
}
```


## 忘記密碼
* 不須有token

Request:
```URL
POST /generalPublic/forgotPassword
```


Body:
欄位 | 型態 | 必填 | 說明
-|-|-|-
countryCode | String | Y | 電話國碼, e.g.台灣為+886
phone | String | Y | 手機號碼(台灣手機號碼格式09.....)
password | String | Y | 密碼, 需加密
otpId | String | Y | otpId, 確保有成功驗證過otp

```javascript
{
    "countryCode": "+886",
    "phone":"0987654321",
    "password": "LoM7aCNhoIHkcO+eoRUlKA==",
    "otpId": "a72ccbc3-947d-467e-914e-3928dad3270e"
}
```

Response:
```javascript
{
    "httpCode": 200,
    "result": {
        "data": "true"
    }
}
```

ErrorMsg:
```javascript
// 密碼重複未變更 PASSWORD_SAME_AS_OLD
{
    "errorMsg": "SERVICE_ERROR.PASSWORD_SAME_AS_OLD",
    "httpCode": 422
}

// 舊密碼錯誤
{
    "errorMsg":"SERVICE_ERROR.PASSWORD_ERROR",
    "httpCode": 422
}

// 帳號不存在
{
    "errorMsg": "SERVICE_ERROR.ACCOUNT_NOT_EXISTS",
    "httpCode": 422
}

// OTP驗證失敗
{
    "errorMsg": "SERVICE_ERROR.OTP_VALIDATE_FAIL",
    "httpCode": 422
}
```


## 取得App目前最新版本號
* 不須有token

Request:
```URL
GET /api/appLatestVersion
```


Response:
```javascript
{
    "httpCode": 200,
    "result": {
        "data": {
            "app_version_android": "2.0.8",
            "app_version_ios": "2.0.8"
        }
    }
}
```


## 取得error code mappings
* 不須有token

Request:
```URL
GET /api/error-code-mappings
```

Response:

欄位 | 型態 | 說明
-|-|-
httpCode | int | http status code
errorCodes | errorCode json array | 錯誤碼json array

* errorCodes

欄位 | 型態 | 說明
-|-|-
httpCode | int | http status code
errorCode | string | errorCode, 對應到執行API後返回的error response json裡的"errorMsg"欄位
errorMessage | string | 對應到的錯誤訊息(預設語系)
langs | json array | 多語系json array

* langs

欄位 | 型態 | 說明
-|-|-
lang | string | 語系, 目前可用語系有 zh_TW(正體中文), en(英文)
message | string | 該語系訊息 

```javascript
{
    "httpCode": 200,
    "result": {
        "data": [
            {
                "httpCode": 400,
                "errorCodes": [
                    {
                        "httpCode": 400,
                        "errorCode": "API_ERROR.USER_INFO_ERROR",
                        "errorMessage": "憑證資訊錯誤",
                        "langs": [
                            {
                                "lang": "zh_TW",
                                "message": "憑證資訊錯誤"
                            },
                            {
                                "lang": "en",
                                "message": "Certificate Error"
                            }
                        ]
                    },
                    {
                        "httpCode": 400,
                        "errorCode": "API_ERROR.NOT_EXIST",
                        "errorMessage": "該資料不存在",
                        "langs": [
                            {
                                "lang": "zh_TW",
                                "message": "該資料不存在"
                            },
                            {
                                "lang": "en",
                                "message": "No Data"
                            }
                        ]
                    },
                    ...
                ]
            },
            {
                "httpCode": 401,
                "errorCodes": [
                    {
                        "httpCode": 401,
                        "errorCode": "API_ERROR.UNAUTHORIZED",
                        "errorMessage": "未經授權",
                        "langs": [
                            {
                                "lang": "zh_TW",
                                "message": "未經授權"
                            },
                            {
                                "lang": "en",
                                "message": "Unauthorized"
                            }
                        ]
                    }
                ]
            },
            {
                "httpCode": 403,
                "errorCodes": [
                    {
                        "httpCode": 403,
                        "errorCode": "API_ERROR.PERMISSION_DENIED",
                        "errorMessage": "權限限制",
                        "langs": [
                            {
                                "lang": "zh_TW",
                                "message": "權限限制"
                            },
                            {
                                "lang": "en",
                                "message": "Permission Denied"
                            }
                        ]
                    }
                ]
            },
            {
                "httpCode": 422,
                "errorCodes": [
                    {
                        "httpCode": 422,
                        "errorCode": "SERVICE_ERROR.MEMBER_NOT_EXIST",
                        "errorMessage": "成員不存在",
                        "langs": [
                            {
                                "lang": "zh_TW",
                                "message": "成員不存在"
                            },
                            {
                                "lang": "en",
                                "message": "Member does not exist."
                            }
                        ]
                    },
                    ...
                ]
            }
        ]
    }
}
```
