Access Token

Tìm hiểu cách sử dụng và quản lý Access Token để truy cập API của SePay.


Giới thiệu về Access Token

  • Access Token là chuỗi ký tự được SePay cấp cho ứng dụng của bạn sau khi quá trình xác thực OAuth2 thành công. Token này đóng vai trò như một "chìa khóa" tạm thời để truy cập vào các API của SePay thay mặt cho người dùng.

Access Token của SePay có thời hạn giới hạn 1 giờ và đi kèm với Refresh Token có thời hạn dài là 1 tháng để cấp lại Access Token mới khi hết hạn.

Cấu trúc của Access Token

  • Access Token của SePay tuân theo chuẩn JWT (JSON Web Token) và bao gồm 3 phần, phân tách bởi dấu chấm (.):

    header.payload.signature
    • Header: Chứa thông tin về loại token và thuật toán mã hóa
    • Payload: Chứa các claims (thông tin) như ID người dùng, phạm vi quyền, thời gian hết hạn
    • Signature: Chữ ký để xác minh token không bị sửa đổi
  • Ví dụ về nội dung giải mã của một JWT Access Token:

RESPONSE
{
  "iss": "https://my.sepay.vn",
  "sub": "12345",
  "aud": "client_67890",
  "exp": 1740541044,
  "iat": 1740537444,
  "scope": "profile bank-account:read transaction:read"
}
iss (issuer)

SePay - đơn vị cấp token

sub (subject)

ID của người dùng đã cấp quyền

aud (audience)

Client ID của ứng dụng

exp (expiration time)

Thời gian hết hạn của token

iat (issued at)

Thời gian token được cấp

scope

Phạm vi quyền được cấp

Lưu ý

Mặc dù JWT có thể giải mã để đọc thông tin, nhưng bạn không nên dựa vào việc giải mã token ở phía client để xác thực. Chữ ký JWT chỉ có thể được xác minh bởi SePay.

Sử dụng Access Token

  • Để sử dụng Access Token, bạn cần thêm nó vào header Authorization trong mỗi yêu cầu API với prefix Bearer:

    GET https://my.sepay.vn/api/v1/bank-accounts 
    Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL215LnNlcGF5LnZuIiwic3ViIjoidXNlcl8xMjM0NSIsImF1ZCI6ImNsaWVudF82Nzg5MCIsImV4cCI6MTY3OTUzMTQwMiwiaWF0IjoxNjc5NTI3ODAyLCJzY29wZSI6ImJhbmtfYWNjb3VudDpyZWFkIHRyYW5zYWN0aW9uOnJlYWQifQ.signature
  • Dưới đây là ví dụ sử dụng Access Token với một số ngôn ngữ lập trình phổ biến:

    bash

Lưu trữ Access Token an toàn

  • Việc lưu trữ an toàn Access Token và Refresh Token là rất quan trọng để bảo vệ dữ liệu người dùng. Dưới đây là các thực hành tốt nhất:

Ứng dụng Web (Server-side)

Phương pháp lưu trữ được khuyến nghị
  • Lưu trữ trong session server
  • Lưu trong database có mã hóa
  • Dùng cookie có thuộc tính HttpOnly và Secure
Cần tránh
  • Lưu trong localStorage hoặc sessionStorage
  • Lưu trong cookie không bảo mật

Ứng dụng SPA (Single Page Application)

Phương pháp lưu trữ được khuyến nghị
  • Sử dụng BFF (Backend For Frontend) pattern
  • Cookie HttpOnly được thiết lập từ server
Cần tránh
  • Lưu trữ trong localStorage hoặc sessionStorage
  • Lưu trong biến JavaScript

Ứng dụng Mobile

Phương pháp lưu trữ được khuyến nghị
  • iOS: Keychain Services
  • Android: EncryptedSharedPreferences
  • Android: Android Keystore System
Cần tránh
  • SharedPreferences không mã hóa
  • UserDefaults không bảo mật
  • Lưu trong bộ nhớ ứng dụng thông thường
Cảnh báo bảo mật

Không bao giờ lưu trữ client_secret trong mã nguồn phía client hoặc ứng dụng mobile. Luôn giữ client_secret ở phía server.

Quản lý Token hết hạn

  • Access Token có thời hạn giới hạn (mặc định là 1 giờ). Khi token hết hạn, ứng dụng của bạn cần xử lý tình huống này để duy trì trải nghiệm người dùng liên tục.

  • Chiến lược xử lý token hết hạn:

    • Làm mới trước khi hết hạn: Theo dõi thời gian sắp hết hạn và chủ động làm mới token trước khi API trả về lỗi. Bạn có thể tính toán thời điểm làm mới dựa trên trường expires_in trong phản hồi token.
    • Xử lý lỗi 401: Khi API trả về mã lỗi 401 Unauthorized, thực hiện việc làm mới token và thử lại yêu cầu.
  • Dưới đây là mẫu code xử lý token hết hạn và tự động làm mới token:

PHP
function makeApiRequest($url, $accessToken) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Authorization: Bearer ' . $accessToken
    ]);

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($httpCode === 401) {
        // Token hết hạn, làm mới token
        $newTokens = refreshAccessToken();
        $accessToken = $newTokens['access_token'];

        // Thử lại yêu cầu với token mới
        return makeApiRequest($url, $accessToken);
    }

    return json_decode($response, true);
}

function refreshAccessToken() {
    $url = 'https://my.sepay.vn/oauth/token';
    $data = [
        'grant_type' => 'refresh_token',
        'refresh_token' => 'YOUR_REFRESH_TOKEN',
        'client_id' => 'YOUR_CLIENT_ID',
        'client_secret' => 'YOUR_CLIENT_SECRET',
    ];

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));

    $response = curl_exec($ch);
    curl_close($ch);

    return json_decode($response, true);
}

$bankAccounts = makeApiRequest('https://my.sepay.vn/api/v1/bank-accounts', 'YOUR_ACCESS_TOKEN');
print_r($bankAccounts);

Xử lý lỗi liên quan đến Token

  • Khi làm việc với Access Token, bạn có thể gặp phải các lỗi sau:
HTTP StatusMã lỗiMô tảXử lý
401invalid_tokenToken không hợp lệ hoặc hết hạnLàm mới token hoặc yêu cầu người dùng đăng nhập lại
401expired_tokenToken đã hết hạnSử dụng refresh token để lấy token mới
403insufficient_scopeToken không có quyền truy cập resourceYêu cầu lại token với phạm vi quyền hạn rộng hơn
400invalid_grantRefresh token không hợp lệ hoặc hết hạnYêu cầu người dùng đăng nhập lại

Bước tiếp theo

  • Sau khi hiểu rõ về cách sử dụng và quản lý Access Token, bạn đã sẵn sàng để tìm hiểu về các API resources của SePay.