คู่มือสำหรับแอปมือถือเนทีฟ: การเข้าถึงหลายบัญชีธุรกิจและโฟลว์ OAuth

OAuth Android iOS มือถือ API หลายบัญชีธุรกิจ PKCE

ReceiptRoller มีกรณีที่ผู้ใช้ 1 คนสังกัดหลายบัญชีธุรกิจอยู่บ่อยครั้ง หากต้องการทำ UI「สลับบัญชีธุรกิจ」ในแอปมือถือเนทีฟ (Android / iOS) การใช้แพตเทิร์นในคู่มือนี้จะทำให้ล็อกอินเพียงครั้งเดียวก็เข้าถึงข้อมูลของทุกบัญชีธุรกิจได้

กลไก

ประกอบด้วย 3 กลไกดังนี้

  1. access token แบบ user-scoped — โทเคนไม่ผูกกับบัญชีธุรกิจใดบัญชีหนึ่ง (AuthorizedOrganizationId = null, ตั้งค่าเฉพาะ AuthorizedUserId)
  2. GET /api/v1/me/organizations — คืนรายการบัญชีธุรกิจที่ผู้ใช้สังกัด
  3. แนบ ?organizationId= ให้แต่ละ API — ฝั่งเซิร์ฟเวอร์ตรวจสอบความเป็นสมาชิกทุกครั้ง

ด้วยวิธีนี้ ผู้ใช้ทำ OAuth login แบบเว็บเบราว์เซอร์เพียงครั้งเดียว ก็สามารถอ้างอิง・ดำเนินการโดยสลับไปมาระหว่างทุกบัญชีธุรกิจที่สังกัดได้

การตั้งค่าตอนลงทะเบียนแอป

หากต้องการใช้แพตเทิร์นนี้ ให้ปิดเช็กบ็อกซ์ 「ผูกโทเคนกับบัญชีธุรกิจเดียวตอนอนุมัติ」ตอนลงทะเบียนแอป ตั้งค่าได้ที่หน้าสร้างแอปในแดชบอร์ดนักพัฒนา

  • เปิดไว้ (ค่าเริ่มต้น) → หน้าจออนุมัติจะแสดงไดอะล็อกเลือกบัญชีธุรกิจ และโทเคนจะผูกกับบัญชีที่เลือก 1 บัญชี (เหมาะสำหรับเว็บแอปทั่วไป・การเชื่อมต่อฝั่งเซิร์ฟเวอร์)
  • ปิด → หน้าจออนุมัติจะไม่แสดงการเลือกบัญชี และจะออกโทเคนแบบ user-scoped (คือเป้าหมายของคู่มือนี้)

ในหน้ารายละเอียดของรายการแอป แอปที่ปิดแฟล็กนี้จะแสดงแบดจ์「รองรับหลายบัญชี」

โฟลว์การอนุมัติ OAuth (PKCE + Chrome Custom Tabs / ASWebAuthenticationSession)

ปฏิบัติตามรูปแบบที่ RFC 8252 (OAuth 2.0 for Native Apps) และ OAuth 2.1 แนะนำ หลีกเลี่ยง WebView ในแอป และใช้คอมโพเนนต์เบราว์เซอร์ของระบบ

  • Android: androidx.browser.customtabs.CustomTabsIntent
  • iOS: AuthenticationServices.ASWebAuthenticationSession

ขั้นตอน

  1. ลงทะเบียน OAuth client
    • สร้างเองจากแดชบอร์ดนักพัฒนา: สร้างแอปพลิเคชันใหม่
    • ปิดเช็กบ็อกซ์「ผูกโทเคนกับบัญชีธุรกิจเดียวตอนอนุมัติ」
    • redirect_uri ระบุเป็น custom scheme (ตัวอย่าง: com.example.rrstore://oauth/callback) หรือ App Links / Universal Links แบบ HTTPS
  2. สร้างพารามิเตอร์ PKCE
    • code_verifier: สตริงสุ่ม 43〜128 อักขระ
    • code_challenge: BASE64URL(SHA256(code_verifier))
    • state: ค่าสุ่มสำหรับป้องกัน CSRF
  3. เปิด /oauth/authorize ในเบราว์เซอร์ของระบบ
    https://receiptroller.io/oauth/authorize
      ?response_type=code
      &client_id={your_client_id}
      &redirect_uri={your_redirect_uri}
      &scope=sales.read sns.content.read sns.audience.read analytics.read store.customers.read store.flyers.read
      &state={state}
      &code_challenge={code_challenge}
      &code_challenge_method=S256

    หากผู้ใช้ยังไม่ล็อกอินจะถูกนำไปที่ /Identity/Account/Login และหลังล็อกอินจะผ่านหน้าจอยินยอม (แสดงเฉพาะสโคปที่ร้องขอ・ไม่มีการเลือกบัญชีธุรกิจ) แล้วกลับมาที่ redirect_uri ของแอป

    หมายเหตุ: หากไม่ได้ปิด「ผูกโทเคนกับบัญชีธุรกิจเดียวตอนอนุมัติ」ตรงนี้จะมีดรอปดาวน์ให้เลือก「จะเข้าถึงบัญชีธุรกิจใด」เพิ่มขึ้นมา หากต้องการรองรับหลายบัญชีต้องปิดเสมอ

  4. แลกเปลี่ยน authorization code เป็น access token
    POST https://receiptroller.io/api/v1/auth/token
    Content-Type: application/x-www-form-urlencoded
    
    grant_type=authorization_code
    &code={code_from_redirect}
    &redirect_uri={your_redirect_uri}
    &client_id={your_client_id}
    &client_secret={your_client_secret}
    &code_verifier={code_verifier}

    การตอบกลับเป็น JSON แบบ snake_case ตาม RFC 6749 §5.1

    {
      "access_token": "...",
      "refresh_token": "...",
      "token_type": "Bearer",
      "expires_in": 3600,
      "scope": "sal…
                        
วันที่เผยแพร่: 2569-05-26 วันที่อัปเดต: 2569-07-06
แท็ก
API (22) OAuth (15) Android (10) iOS (9) Webhook (8) api (7) oauth (5) getting-started (4) การลงทะเบียนแอป (4) การแก้ปัญหา (4)
บทความที่เกี่ยวข้อง