Luồng xác thực

Tìm hiểu chi tiết về luồng xác thực OAuth2 và cách triển khai trong ứng dụng của bạn.


Tổng quan luồng xác thực

SePay triển khai OAuth2 theo luồng Authorization Code, một trong những luồng xác thực phổ biến và an toàn nhất của OAuth2. Luồng này phù hợp cho hầu hết các ứng dụng web và ứng dụng server-side.

OAuth2 SePay Flowchart
Nhấn để phóng to

Luồng xác thực OAuth2 trong SePay bao gồm các bước sau:

  • Bước 1: Ứng dụng yêu cầu ủy quyền từ người dùng bằng cách chuyển hướng đến URL ủy quyền của SePay
  • Bước 2: Người dùng đăng nhập vào SePay và đồng ý cấp quyền cho ứng dụng
  • Bước 3: SePay chuyển hướng về redirect URI của ứng dụng kèm theo mã ủy quyền (authorization code)
  • Bước 4: Ứng dụng đổi mã ủy quyền lấy access token từ SePay
  • Bước 5: Ứng dụng sử dụng access token để gọi các API của SePay

Bước 1: Yêu cầu ủy quyền

Để bắt đầu quá trình xác thực, chuyển hướng người dùng đến URL ủy quyền của SePay:

URL
https://my.sepay.vn/oauth/authorize?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&scope=bank-account:read transaction:read&state=RANDOM_STATE_VALUE

Giải thích tham số trên URL:

response_typestringrequired
Phải là code cho luồng Authorization Code
client_idstringrequired
Client ID của ứng dụng bạn, nhận được khi đăng ký ứng dụng
redirect_uristringrequired
URL nhận mã ủy quyền, phải khớp với URL đã đăng ký
scopestringrequired
Các quyền truy cập yêu cầu, phân tách bằng dấu cách
statestringrequired
Giá trị ngẫu nhiên để ngăn tấn công CSRF, sẽ được trả về không thay đổi
Bảo mật quan trọng

Tham số state nên được sử dụng để bảo vệ khỏi tấn công CSRF. Tạo một giá trị ngẫu nhiên, lưu trong session và xác minh khi nhận callback.

Bước 2: Người dùng đồng ý cấp quyền

Sau khi chuyển hướng đến URL ủy quyền, người dùng sẽ thấy màn hình đăng nhập SePay (nếu chưa đăng nhập) và sau đó là màn hình xác nhận cấp quyền:

OAuth2 SePay
Nhấn để phóng to

Màn hình này hiển thị:

  • Tên ứng dụng yêu cầu truy cập
  • Các quyền mà ứng dụng yêu cầu
  • Nút đồng ý hoặc từ chối cấp quyền

Bước 3: Nhận mã ủy quyền

Sau khi người dùng đồng ý cấp quyền, SePay sẽ chuyển hướng về redirect_uri của bạn kèm theo mã ủy quyền:

URL
https://your-app.com/callback?code=AUTHORIZATION_CODE&state=RANDOM_STATE_VALUE

Ứng dụng của bạn cần:

  • Xác minh tham số state khớp với giá trị đã gửi trước đó
  • Lấy mã ủy quyền từ tham số code
Lưu ý

Mã ủy quyền chỉ có hiệu lực trong một thời gian ngắn (thường là 5 phút) và chỉ có thể sử dụng một lần. Bạn cần đổi nó lấy access token ngay sau khi nhận được.

Bước 4: Đổi mã ủy quyền lấy access token

Sau khi nhận được mã ủy quyền, bạn cần đổi nó lấy access token bằng cách gửi yêu cầu POST đến endpoint token của SePay:

POST
https://my.sepay.vn/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
code=AUTHORIZATION_CODE
redirect_uri=YOUR_REDIRECT_URI
client_id=YOUR_CLIENT_ID
client_secret=YOUR_CLIENT_SECRET

Giải thích tham số:

grant_typestringrequired
Phải là authorization_code
codestringrequired
Mã ủy quyền nhận được từ bước trước
redirect_uristringrequired
URL chuyển hướng giống với URL đã sử dụng ở bước 1
client_idstringrequired
Client ID của ứng dụng bạn
client_secretstringrequired
Client Secret của ứng dụng bạn
>
>
>
>
>
>
>
curl -X POST "https://my.sepay.vn/oauth/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "code=AUTHORIZATION_CODE" \
-d "redirect_uri=YOUR_REDIRECT_URI" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET"
RESPONSE
{
  "access_token": "ACCESS_TOKEN",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "REFRESH_TOKEN"
}
access_tokenstring

Token dùng để gọi API SePay

token_typestring

Loại token, luôn là Bearer

expires_ininteger

Thời gian hiệu lực của token (tính bằng giây)

refresh_tokenstring

Token dùng để lấy access token mới khi hết hạn

Quan trọng

Yêu cầu đổi token này phải được thực hiện từ phía máy chủ, không bao giờ thực hiện từ phía client vì cần sử dụng client_secret.

Bước 5: Sử dụng access token để gọi API

Sau khi nhận được access token, bạn có thể sử dụng nó để gọi các API của SePay bằng cách thêm vào header Authorization:

GET
https://my.sepay.vn/api/v1/bank-accounts
Authorization: Bearer ACCESS_TOKEN

Dưới đây là ví dụ sử dụng cURL:

JScURL
1
curl -H 'Authorization: Bearer ACCESS_TOKEN' https://my.sepay.vn/api/v1/bank-accounts

Bước 6: Làm mới access token

Access token chỉ có hiệu lực trong một khoảng thời gian giới hạn (thường là 1 giờ). Khi access token hết hạn, bạn cần sử dụng refresh token để lấy token mới mà không yêu cầu người dùng xác thực lại:

POST
https://my.sepay.vn/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token
refresh_token=REFRESH_TOKEN
client_id=YOUR_CLIENT_ID
client_secret=YOUR_CLIENT_SECRET

Giải thích tham số:

grant_typestringrequired
Phải là refresh_token
refresh_tokenstringrequired
Refresh token nhận được khi lấy access token
client_idstringrequired
Client ID của ứng dụng bạn
client_secretstringrequired
Client Secret của ứng dụng bạn
>
>
>
>
>
>
curl -X POST "https://my.sepay.vn/oauth/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=refresh_token" \
-d "refresh_token=REFRESH_TOKEN" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET"

Phản hồi tương tự như khi đổi mã ủy quyền, bao gồm access token mới, refresh token mới và thời gian hết hạn.

RESPONSE
{
  "access_token": "ACCESS_TOKEN",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "REFRESH_TOKEN"
}
Mẹo

Nên lưu trữ refresh token an toàn và thực hiện làm mới token tự động khi access token gần hết hạn hoặc khi API trả về lỗi 401 Unauthorized.

Xử lý lỗi

Khi có lỗi xảy ra trong quá trình xác thực, SePay sẽ trả về mã lỗi tương ứng. Dưới đây là một số lỗi phổ biến:

Mã lỗiMô tảGiải pháp
invalid_requestYêu cầu thiếu tham số bắt buộc hoặc chứa tham số không hợp lệKiểm tra lại tất cả tham số trong yêu cầu
invalid_clientXác thực client thất bạiKiểm tra lại client_idclient_secret
invalid_grantMã ủy quyền hoặc refresh token không hợp lệ hoặc đã hết hạnYêu cầu người dùng xác thực lại hoặc kiểm tra refresh token
unauthorized_clientClient không được phép yêu cầu authorization codeKiểm tra lại cấu hình ứng dụng
access_deniedNgười dùng từ chối cấp quyềnThông báo cho người dùng rằng họ cần cấp quyền để sử dụng ứng dụng
unsupported_grant_typeServer không hỗ trợ kiểu grant được yêu cầuKiểm tra tham số grant_type
invalid_scopePhạm vi yêu cầu không hợp lệ, không được nhận diện hoặc vượt quá phạm vi đã đăng kýKiểm tra lại phạm vi yêu cầu

Phản hồi lỗi có định dạng:

JSON
{
  "error": "invalid_grant",
  "error_description": "Authorization code expired"
}

Bước tiếp theo

Sau khi hiểu rõ về luồng xác thực OAuth2, bạn đã sẵn sàng để triển khai trong ứng dụng của mình. Tiếp theo, hãy tìm hiểu về cách sử dụng Access Token với các API của SePay.