Backend Note

Một vài note khi làm việc với BE

Webhook

Tổng quan

Webhook thực chất chỉ là một request từ remote server (hook server) đến web của bạn

  • Hook Header lưu ở global $_SERVER
  • Payload thì @file_get_contents('php://input')

Cách tạo webhook từ Postman

  • Coi Postman chính là server hook và bắn request đến website của bạn dưới dạng một Request. Body dạng JSON là dữ liệu của webhook. Ví dụ body truyền JSON như sau với stripe
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
{
"id": "evt_1CiPtv2eZvKYlo2CcUZsDcO6",
"object": "event",
"api_version": "2018-05-21",
"created": 1530291411,
"data": {
"object": {
"id": "src_1CiPsl2eZvKYlo2CVVyt3LKy",
"object": "source",
"amount": 1000,
"client_secret": "src_client_secret_D8hHhtdrGWQyK8bLM4M3uFQ6",
"created": 1530291339,
"currency": "eur",
"flow": "redirect",
"livemode": false,
"metadata": {},
"owner": {
"address": null,
"email": null,
"name": null,
"phone": null,
"verified_address": null,
"verified_email": null,
"verified_name": "Jenny Rosen",
"verified_phone": null
},
"redirect": {
"failure_reason": null,
"return_url": "https://minkpolice.com",
"status": "succeeded",
"url": "https://hooks.stripe.com/redirect/authenticate/src_1CiPsl2eZvKYlo2CVVyt3LKy?client_secret=src_client_secret_D8hHhtdrGWQyK8bLM4M3uFQ6"
},
"sofort": {
"country": "DE",
"bank_code": "DEUT",
"bank_name": "Deutsche Bank",
"bic": "DEUTDE2H",
"iban_last4": "3000",
"statement_descriptor": null,
"preferred_language": null
},
"statement_descriptor": null,
"status": "chargeable",
"type": "sofort",
"usage": "single_use"
}
},
"livemode": false,
"pending_webhooks": 0,
"request": {
"id": null,
"idempotency_key": null
},
"type": "source.chargeable"
}

Endpoint: Route xử lý request từ hook

Nhờ vậy, sự kiện source.changeable được kích hoạt từ Postman mà bạn không phải thay đổi source trên stripe, đỡ 1 bước để test nhanh hơn

Lấy dữ liệu

  • Cách lấy dữ liệu đúng nhất
    • Header: Global $_SERVER
    • Body (Payload): @file_get_contents('php://input')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# https://stripe.com/docs/webhooks
$payload = @file_get_contents('php://input');
$event = null;

try {
$event = \Stripe\Event::constructFrom(
json_decode($payload, true)
);
} catch(\UnexpectedValueException $e) {
// Invalid payload
http_response_code(400);
exit();
}

// Handle the event
switch ($event->type) {
case 'payment_intent.succeeded':
$paymentIntent = $event->data->object; // contains a \Stripe\PaymentIntent
// Then define and call a method to handle the successful payment intent.
// handlePaymentIntentSucceeded($paymentIntent);
break;
case 'payment_method.attached':
$paymentMethod = $event->data->object; // contains a \Stripe\PaymentMethod
// Then define and call a method to handle the successful attachment of a PaymentMethod.
// handlePaymentMethodAttached($paymentMethod);
break;
// ... handle other event types
default:
echo 'Received unknown event type ' . $event->type;
}

http_response_code(200);
  • Cách lấy này để xác thực chữ ký (nếu muốn) một cách chính xác. Vì tôi đã từng gặp phải trường hợp kiểm tra chữ ký, ký lên cả body nhưng dùng các hàm của Laravel (kết quả như nhau) nhưng chữ ký sai
  • Với Laravel, bạn có thể lấy dữ liệu từ biến $request vì như đã nói ở trên, bản chất webhook cũng là gửi một request đến server bên thứ 3
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    use Illuminate\Http\Request;

    class WebhookController extends Controller
    {
    /**
    * Process webhook event.
    *
    * @param \Illuminate\Http\Request $request
    * @return \Illuminate\Http\Response
    */
    public function index(Request $request)
    {
    $header = $request->header('signature');
    $payload = $request->all();

    //
    }
    }

Phân tích các thông số video và các file media

getID3() is a PHP script that extracts useful information from MP3s & other multimedia file formats: https://www.getid3.org/

1
composer require james-heinrich/getid3
  • Sử dụng
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php
...
use getID3;
...

class VideoController extends Controller
{
private $getID3;

public function __construct(getID3 $getID3)
{
$this->getID3 = $getID3;
}

public function uploadVideo(Request $request)
{
$request->validate([
'file' => 'required',
]);

// Sử dụng analyze method để phân tích các thông số file
$fileInfo = $this->getID3->analyze($request->file);

dd($fileInfo);
}
}
?>

SEO

Tổng hợp

  • Yêu cầu Icon, logo, img có title, alt theo keyword
  • Nén dung lượng Icon, logo, img:
    • Logo: nhỏ hơn 10 KB
    • Icon: (from disk cache).
    • Img: nhỏ hơn 100 KB. Ảnh cần phù hợp với viewport, tránh sử dụng css để căn chỉnh width, height
  • Bổ sung Favicon.
  • Sắp xếp menu dựa trên chuyên mục cần SEO.
  • Link được tự động lấy theo title bài viết (slug)
  • Các link không SEO, link trống, link out để dưới dạng nofollow
  • Xây dựng title, description meta duy nhất cho mỗi page
  • Xây dựng H1, H2, H3, H4.
  • Bổ sung Schema (sitemap.xml): https://github.com/spatie/laravel-sitemap
  • Xây dựng Title, Description, Img khi share lên mạng xã hội
  • Tự động lấy tiêu đề làm alt cho ảnh khi người viết không thêm. Nén ảnh về dưới 100 KB. (sử dụng định dạng webp có thể tham khảo link:
    https://dieuhau.com/su-dung-file-webp-trong-wordpress/

Others

  • Tốc độ: Tốc độ tải trang trên Desktop đạt trên 90 điểm, Mobile trên 40 điểm.

  • Thông báo: Xuất hiện bảng “Đăng ký nhận thông báo” sau khi vào trang được 30s (xem ảnh của trang facebook bên cạnh)

Author

Ming

Posted on

2022-02-04

Updated on

2022-02-05

Licensed under

Comments