# 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)~~ * ~~重置密碼改成以生日(yyyyMMdd)當密碼,登入時一樣要要求變更密碼一次~~ 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." } ] }, ... ] } ] } } ```