# Tích hợp OAuth2

#### Trước khi bắt đầu

Trước khi bắt đầu sử dụng Oauth2 của Casso, bạn cần phải:

* Có một tài khoản Casso.
* [Đăng ký một ứng dụng liên kết ](https://forms.gle/9Q6cvPLLmXNwpo366)với tài khoản developer của bạn.

#### Cách hoạt động

Casso hỗ trợ [Oauth 2.0 Authorization Code grant type](https://developer.okta.com/blog/2018/04/10/oauth-authorization-code-grant-type), được chia thành 4 bước cơ bản như sau:

1. Ứng dụng của bạn sẽ mở một cửa sổ trình duyệt để đưa người dùng đến Casso OAuth2.
2. Người dùng xem xét các quyền được yêu cầu và cấp quyền truy cập ứng dụng.
3. Người dùng được chuyển hướng trở lại ứng dụng với mã ủy quyền(authorization code) trong chuỗi truy vấn(query params).
4. Ứng dụng gửi yêu cầu đến Casso OAuth2 để trao đổi mã ủy quyền(authorization code) để lấy **`access token`**.

#### Hướng dẫn

* [**Lấy OAuth2 token**](#lay-oauth2-token): Cách ủy quyền ứng dụng của bạn với người dùng.
* [**Sử dụng OAuth2 token**](#su-dung-oauth2-token): Cách thực hiện một truy vấn với token.
* [**Lấy lại OAuth2 token**](#lay-lai-oauth-2-token): Cách sử dụng refresh token do Casso cung cấp.

## Lấy OAuth2 token

#### Bước 1: Tạo một authorization URL và hướng người dùng đến Oauth2 của Casso.

Khi một người dùng truy vấn tới hệ thống Oauth2 của Casso, đầu tiên sẽ phải tạo một authorization URL. Điều này sẽ xác định ứng dụng và phạm vi tài nguyên mà ứng dụng yêu cầu quyền truy cập thay cho người dùng. Các tham số truy vấn bạn có thể truyền như một phần của authorization URL được hiển thị ở dưới.&#x20;

| Tham số         | Bắt buộc | Mô tả                                                                                                                                                                 | Ví dụ                                   |
| --------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- |
| `client_id`     | Có       | Client ID dùng để xác định ứng dụng của bạn.                                                                                                                          | `84be6ce9-6610-42d5-9cf1-acd85a5574cb`  |
| `scope`         | Có       | Các phạm vi ứng dụng của bạn đang yêu cầu, được phân tách bằng dấu cách được mã hóa URL.                                                                              | `webhook%20transaction`                 |
| `redirect_uri`  | Có       | URL mà người dùng sẽ được chuyển hướng đến sau khi họ ủy quyền cho ứng dụng của bạn trong các phạm vi được yêu cầu. Đối với các ứng dụng sản xuất, https là bắt buộc. | `https://www.example.com/auth-callback` |
| `response_type` | Có       | Loại phản hồi                                                                                                                                                         | `code`                                  |
| `state`         | Không    | Đây là thông số khi bạn gửi lên như nào thì lúc bạn nhận authorization code thì nó vẫn như vậy.                                                                       | `84be6ce9661042d59cf`                   |

Khi bạn đã tạo xong authorization URL của mình, hãy bắt đầu tiến trình OAuth2 bằng cách đưa người dùng đến URL đó.

#### Ví dụ

Sử dụng một server-side redirect:

```javascript
// Build the auth URL
const authUrl =
  'https://oauth.casso.vn/auth/authorize' +
  `?client_id=${encodeURIComponent(CLIENT_ID)}` +
  `&scope=${encodeURIComponent(SCOPES)}` +
  `&redirect_uri=${encodeURIComponent(REDIRECT_URI)}` +
  `&response_type=${encodeURIComponent(RESPONSE_TYPE)}`;

// Redirect the user
return res.redirect(authUrl);
```

Sử dụng đương dẫn HTML:

```javascript
<a href="https://oauth.casso.vn/auth/authorize?scope=webhook%20transaction&redirect_uri=https://www.example.com/auth-callback&client_id=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx">One click to Casso</a>
```

#### Bước 2: Casso nhắc nhở người dùng chấp thuận&#x20;

Casso hiển thị cửa sổ cho người dùng đồng ý, hiển thị tên ứng dụng của bạn và mô tả ngắn gọn về các dịch vụ API của Casso mà họ đang yêu cầu quyền truy cập. Sau đó, người dùng có thể cấp quyền truy cập doanh nghiệp của họ cho ứng dụng của bạn.

![](https://2849291229-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-McgqoGaNKiqy_6nDeJw%2F-MitNrrGBdFdHJah5rqg%2F-MiuCN3PSFhpIOblrkO1%2Fimage.png?alt=media\&token=1db3c4d9-557c-48bf-896a-5127ec5768b5)

Ứng dụng của bạn không thực hiện bất kỳ điều gì ở giai đoạn này. Sau khi quyền truy cập được người dùng cấp, Casso OAuth2 sẽ gửi kết quả đến **`Callback URL`** được xác định trong authorization URL.

#### Bước 3: Xử lý phản hồi của OAuth2

Khi người dùng đã hoàn tất lời nhắc đồng ý từ Bước 2, OAuth 2.0 server sẽ gửi yêu cầu GET tới **redirect URI** được chỉ định trong authorization URL của bạn. Nếu không có vấn đề gì và người dùng chấp thuận yêu cầu truy cập, yêu cầu tới **redirect URI** sẽ được trả về với tham số truy vấn mã được đính kèm. Nếu người dùng không cấp quyền truy cập, sẽ gửi một yêu cầu lỗi về **redirect URI**.

#### Ví dụ:

```javascript
app.get('/oauth-callback', async (req, res) => {
  if (req.query.code) {
    // Handle the received code
  }
});
```

#### Bước 4: Trao đổi authorization code để lấy token

Sau khi ứng dụng của bạn nhận được **authorization code** từ OAuth server, ứng dụng có thể trao đổi mã đó để lấy **access token** và **refresh token** bằng cách gửi yêu cầu [POST URL-form encoded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST#example) tới `https://oauth.casso.vn/auth/token` với các giá trị được hiển thị bên dưới.  Cung cấp base64 của **client\_*****id:client\_secret*** dưới dạng **`basic token`** trong Authorization HTTP Header.

| Tham số         | Mô tả                                                                 | Ví dụ                                   |
| --------------- | --------------------------------------------------------------------- | --------------------------------------- |
| `grant_type`    | Bắt buộc là`authorization_code`                                       | `authorization_code`                    |
| `client_id`     | Client ID của ứng dụng của bạn                                        | `84be6ce9-6610-42d5-9cf1-acd85a5574cb`  |
| `client_secret` | Client secret của ứng dụng của bạn                                    | `58dfc671-c650-457f-8a24-3d57bdeab5ac`  |
| `redirect_uri`  | Chuyển hướng tới URI này khi người dùng ủy quyền cho ứng dụng của bạn | `https://www.example.com/auth-callback` |
| `code`          | Authorization code nhận được từ Oauth2 server                         | `6be34af7-6699-41cb-9c41-e02c635bd354`  |

#### Ví dụ:

```javascript
const formData = {
  grant_type: 'authorization_code',
  client_id: CLIENT_ID,
  redirect_uri: REDIRECT_URI,
  code: req.query.code
};

request.post(
  'https://oauth.casso.vn/auth/token', 
  { 
    form: formData,
    headers: {
      Authorization: `Basic ${Buffer.from(CLIENT_ID+":"+CLIENT_SECRET).toString('base64')}`
    } 
  }, (err, data) => {
  // Handle the returned tokens
}
```

Nội dung của phản hồi mã thông báo sẽ là dữ liệu JSON có dạng:&#x20;

```javascript
{
    "refresh_token":"f71345a6-f53d-4191-903c-3823d9adb9e",
    "access_token":"eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxODI5IiwiZXhwIjoxNjMwOTQxMDI4LCeJpYXQiOjE2MzA5MTk0M9.mYA8HFw0HqyoLJAocIzffNw4aG2kA8sHlf2UYNIKhHlazWK2ajbj06Bil4_0NxS6Jiamw3E9Q28tpiU7f9tYA",
    "expires_in":21600,
    "token_type": "bearer"
}
```

{% hint style="info" %}
Note: Access token sẽ hết hạn sau số giây được cung cấp trong trường expires\_in của phản hồi (sáu giờ). Để biết thông tin về cách nhận access token mới, hãy xem [Lấy lại Oauth2 token](#lay-lai-oauth-2-token).
{% endhint %}

## Sử dụng OAuth2 token

Sau khi hoàn tất quy trình authorization code, ứng dụng của bạn được ủy quyền thay người dùng gửi request. Để thực hiện việc này, cung cấp access token dưới dạng bearer token trong Authorization HTTP Header.&#x20;

#### Ví dụ:

```javascript
request.get('https://oauth.casso.vn/v2/transactions?fromDate=2021-04-01&page=4',
  {
    headers: {
      'Authorization': `Bearer ${ACCESS_TOKEN}`,
      'Content-Type': 'application/json'
    }
  },
  (err, data) => {
    // Handle the API response
  }
);
```

## Lấy lại OAuth 2 token

OAuth access token hết hạn định kỳ. Điều này nhằm đảm bảo rằng nếu chúng bị xâm nhập, những kẻ tấn công sẽ chỉ có quyền truy cập trong một thời gian ngắn. Tuổi thọ của access token (sáu giờ theo mặc định) được chỉ định trong trường **`expires_in`** khi **`authorization code`** được trao đổi lấy access token.

Ứng dụng của bạn có thể trao đổi **`refresh token`** đã nhận để lấy **`access token`** mới bằng cách gửi yêu cầu [POST URL-form encoded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST#example) tới **`https://oauth.casso.com/auth/token`** với các giá trị bên dưới. Cung cấp base64 của **client\_*****id:client\_secret*** dưới dạng basic token trong Authorization HTTP Header.

| Tham số         | Mô tả                                                                 | Ví dụ                                   |
| --------------- | --------------------------------------------------------------------- | --------------------------------------- |
| `grant_type`    | Phải là `refresh_token`                                               | `refresh_token`                         |
| `client_id`     | Client ID của ứng dụng của bạn                                        | `84be6ce9-6610-42d5-9cf1-acd85a5574cb`  |
| `client_secret` | Client secret của ứng dụng của bạn                                    | `58dfc671-c650-457f-8a24-3d57bdeab5ac`  |
| `redirect_uri`  | Chuyển hướng tới URI này khi người dùng ủy quyền cho ứng dụng của bạn | `https://www.example.com/auth-callback` |
| `refresh_token` | Refresh token nhận được khi người dùng ủy quyền cho ứng dụng của bạn  | `6be34af7-6699-41cb-9c41-e02c635bd354`  |

#### Ví dụ:

```javascript
const formData = {
  grant_type: 'refresh_token',
  client_id: CLIENT_ID,
  redirect_uri: REDIRECT_URI,
  refresh_token: REFRESH_TOKEN
};

request.post(
  'https://oauth.casso.vn/auth/token', 
  { 
    form: formData, 
    headers: {
      Authorization: `Basic ${Buffer.from(CLIENT_ID+":"+CLIENT_SECRET).toString('base64')}`
    } 
  }, (err, data) => {
  // Handle the returned tokens
}
```

Nội dung của phản hồi mã thông báo sẽ là dữ liệu JSON có dạng:&#x20;

```javascript
{
    "access_token": "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxODI5IiwiZXhwjsIjoxNjMwOTQyODc4LCJpYXQiOjE2MzA5MjEyNzh9.qh0_UkSudFUu_WabtW9wu_j57b3VJ5WEWASLpSklPfrb-EKzrYl4Z4PYkrPIPrLseCPnSXlIDsixp8OkBrh_BW4g",
    "token_type": "bearer",
    "expires_in": 21600
}
```

**`Access token`** mới có thể được sử dụng để thực hiện request thay cho người dùng. Khi **`access token`** mới hết hạn, bạn có thể thực hiện lại các bước tương tự để lấy mã mới.

{% hint style="info" %}
**Refresh token** không có thời gian hết hạn. Mỗi lần **`access token`** hết hạn, bạn thực hiện lại các bước tương tự với **refresh token** để lấy mã mới.
{% endhint %}
