OVIRO LogoOVIRO | Trợ giúp
Platform / Integration

Universal Auth

Luồng OTP redirect cho phép app khác mượn phiên đăng nhập admin. KHÔNG phải SSO provider list.

/universalauthluồng chuyển tiếp xác thực (OTP-based redirect), không phải UI cấu hình SSO provider. Dùng khi external app cần đăng nhập "mượn" phiên admin: app gửi user qua /universalauth với redirect_url + scheme, hệ thống generate OTP rồi redirect về app với OTP đính kèm.

Vị trí menu admin

Không có mục riêng trên menu. Chỉ dùng khi có dự án tích hợp: mở đường dẫn /universalauth kèm tham số do đội kỹ thuật cung cấp.

Đường dẫn hoạt động cả khi chưa đăng nhập: nếu cần, hệ thống chuyển sang trang đăng nhập rồi quay lại đúng liên kết Universal Auth sau khi đăng nhập xong (luồng hash #/universalauth?...).

Người dùng trình duyệt thường vào dạng /#/universalauth?redirect_url=...&scheme=... tùy cách triển khai host admin.

Contract route đã audit

Query params bắt buộc

  • redirect_url (string) - URL đích sau khi có OTP. Frontend hiện chấp nhận URL bắt đầu bằng http:// hoặc https:// sau khi decodeURIComponent; production nên ưu tiên https:// và domain đã được cho phép.
  • scheme (string) - định danh scheme của app khách (sẽ được embed vào URL OTP cuối cùng).

Luồng xử lý

1. User mở /universalauth?redirect_url=...&scheme=...
2. Nếu redirect_url rỗng → hiện ErrorAlert "redirect_url_required" + link đăng nhập (nếu chưa login).
3. Nếu user CHƯA đăng nhập:
   - Build returnUrl = `${origin}/#/universalauth?redirect_url=...&scheme=...` (encode lại).
   - navigate(`/user/login?return=${btoa(returnUrl)}`, {replace: true}).
   - Sau khi login xong, login page redirect về /universalauth → bước 4.
4. Nếu user ĐÃ đăng nhập + redirect_url hợp lệ + scheme hợp lệ:
   - Set processing = true, errors = [].
   - Gọi AccountRepository.getLoginQrOtp(scheme) → lấy OTP.
   - Build redirectUrlWithOtp = `${redirect_url}/otp/${otp}/scheme/${scheme}`.
   - window.location.replace(redirectUrlWithOtp) - full page redirect.
5. Có errors → hiện ErrorAlert + nút "Retry" gọi lại doGetLoginQrOtp.

useRef initOtpRef đảm bảo không gọi OTP nhiều lần (tránh re-trigger khi component re-render).

Validation messages

CodeKhi nào
redirect_url_requiredredirectUrl.length === 0 (query không có hoặc rỗng).
redirect_url_invalidURL không bắt đầu http:// / https:// sau decode.
scheme_invalidScheme rỗng sau decode.

I18n prefix user:universalauth.error.

Giao diện

  • Header: <UniversalAuthHeader>.
  • Body: nếu chưa có redirect_url → <ErrorAlert items={["redirect_url_required"]}> + link /login.
  • Nếu đang lấy OTP → <Spin>.
  • Sau khi window.location.replace mà browser delay → fallback box hiện text "Sau 5 giây nếu trình duyệt không tự động chuyển, vui lòng nhấn link sau:" kèm <a href={fallbackReturnUrl}> để click thủ công.
  • Nếu có lỗi → <ErrorAlert> + nút Retry.

Khi nào dùng

  • App mobile/desktop của Cropany (POS, Storefront admin tools...) cần SSO mượn phiên web admin.
  • Tích hợp app bên thứ ba được phép đăng nhập user của mình.

Bảo mật

  • CHỈ cấu hình redirect_url cho domain tin cậy (whitelist app). Backend nên validate redirect_url thuộc allowlist của tenant - frontend chỉ check format.
  • Không gửi OTP trong URL qua kênh không an toàn - production nên dùng https:// và domain thuộc allowlist.
  • scheme phải là enum cố định ở backend - không cho user truyền tuỳ ý vì có thể bị abuse.

Lưu ý - Lỗi thường gặp

  • redirect_url_invalid mặc dù URL hợp lệ: kiểm tra encode - URL gốc đã encodeURIComponent đúng chưa. Frontend decodeURIComponent 1 lần trước khi check.
  • Browser không tự redirect: rare - dùng fallback link text bên dưới.
  • Lỗi scheme_invalid dù truyền scheme: chuỗi bị empty sau decode. Đảm bảo ?scheme=xxx không phải ?scheme=.
  • Login xong nhưng quay về /universalauth lại bị redirect login lần 2: cookie session không được set đúng domain. Kiểm tra cookie domain config.
  • OTP hợp lệ ngắn hạn: chỉ dùng 1 lần. Gọi lại getLoginQrOtp để có OTP mới.

Ai được xem và chỉnh?

  • Trang không khóa theo một “vai trò menu” riêng: người chưa đăng nhập được chuyển đi đăng nhập trước; sau khi đăng nhập hợp lệ, máy chủ mới cấp OTP qua API.
  • Địa chỉ đích (redirect_url): phải do backend tin cậy (danh sách cho phép); giao diện chỉ kiểm tra dạng URL http/https, không thay cho kiểm tra an toàn phía máy chủ.

On this page