WhyPik DocsVề trang chính

Bắt đầu / Hướng dẫn từng bước

First Start: tích hợp Angular

Làm từng bước với một ứng dụng Angular chạy phía trình duyệt. Đường nhanh dùng memory session; bản chạy trên WhyPik Hosting có thể dùng cookie cùng origin.

1. Chuẩn bị Project và HTTPS

Đăng nhập app, tạo/chọn dự án và mở Authentication từ tổng quan. Ở Tổng quan hoặc Authentication → API & SDK, bấm biểu tượng sao chép cạnh PROJECT_UUID (nhãn Sao chép UUID) cho SDK, không dùng Mã dự án (slug) thay UUID. Tên miền mặc định được gợi ý ngay cả khi chưa bật Hosting; muốn website hoạt động ở đó vẫn phải bật Hosting và triển khai website.

Trong cấu hình Auth, để trống tên miền để dùng địa chỉ mặc định hoặc thêm chính xác origin HTTPS nơi Angular chạy. Bấm Enter/dấu phẩy sau mỗi địa chỉ, hoặc dán nhiều dòng; có thể nhập your-app.example không kèm https://. Local cũng cần HTTPS tin cậy.

Hai URL mặc định cho dự án spa: origin https://spa.whypik.app và callback https://spa.whypik.app/auth/callback. Origin không có đường dẫn hoặc dấu / cuối. Dùng hostname hiển thị ở Tổng quan dự án, gồm cả hậu tố tránh trùng nếu có. PROJECT_UUID dùng cho SDK/API, không dùng để ghép hostname.

Mặc định mỗi origin có callback /auth/callback. Ứng dụng Angular phải có route /auth/callback và tự xử lý hành động email như bước Đăng ký và xác minh bên dưới. WhyPik chỉ cho phép địa chỉ này, không tạo trang thay bạn. Nếu dùng route khác, tắt tự tạo callback và nhập URL đầy đủ của route; callback phải thuộc origin đã cho phép.

Với Angular SSR, khởi tạo client ở phía browser; không chia sẻ phiên người dùng bằng singleton trên Node.

Trong Angular Router, khai báo path: "auth/callback" cho component xử lý xác nhận. Khi triển khai Static Hosting, bật SPA mode để mở trực tiếp đường dẫn này vẫn tải ứng dụng. Callback là route của ứng dụng khách, khác với API /.whypik/auth và màn đăng nhập Dashboard WhyPik.

Trường cấu hìnhMặc địnhVí dụ dự án spa
Tên miền ứng dụng được phép (allowed_origins)https://<hostname mặc định của dự án>https://spa.whypik.app
Đường dẫn xác nhận email được phép (redirect_urls)Origin + /auth/callbackhttps://spa.whypik.app/auth/callback

Kết quả cần thấy:Project Auth được bật, origin và callback đúng.

2. Cài SDK

Tải whypik-js.tgz, đặt vào vendor trong ứng dụng Angular và chạy lệnh. Đây là gói tải trực tiếp, không phải gói npm public.

shell
npm install ./vendor/whypik-js.tgz

Kết quả cần thấy:package.json có dependency @whypik/js từ file.

3. Tạo client

Trong Authentication → API & SDK, tạo Public key rồi bấm Cấu hình client ở dòng khóa. Chọn nơi chạy website và Sao chép JSON. Public key của Authentication dùng cho cả Auth/Data; Public Data-only key không dùng đăng nhập.

Dán JSON vào src/app/whypik.config.ts như mẫu, giữ đúng giá trị vừa tải. Dùng satisfies WhyPikOptions để TypeScript giữ đúng kiểu sessionMode. Mẫu memory bên dưới dành cho Hosting bên ngoài; WhyPik Hosting dùng cùng origin theo JSON đã tải. Không đưa BFF/server/account key vào mã client. .env không tự nạp trong Angular.

typescript
import { Injectable, OnDestroy } from "@angular/core";
import { WhyPik, type WhyPikOptions } from "@whypik/js";

// src/app/whypik.config.ts: thay nội dung bằng JSON tải từ Cấu hình client.
export const config = {
  project: "PROJECT_UUID",
  key: "wpk_public_REPLACE_WITH_PROJECT_AUTH_KEY",
  auth: { sessionMode: "memory", autoRestore: false,
    endpoint: "https://app.whypik.com/api/v1/auth/projects/PROJECT_UUID" },
  data: { endpoint: "https://app.whypik.com/api/v1/data/PROJECT_UUID" }
} satisfies WhyPikOptions;

@Injectable({ providedIn: "root" })
export class WhyPikService implements OnDestroy {
  readonly client = new WhyPik(config);
  ngOnDestroy() { this.client.destroy(); }
}

Kết quả cần thấy:Ứng dụng biên dịch, không báo invalid_project_key/origin.

4. Đăng ký và xác minh

Gọi signUp từ form. Trên trang callback, lấy và xóa token khỏi URL trước analytics. Chỉ gọi verifyEmail khi người dùng bấm xác nhận; không tự tiêu thụ token ngay khi mở link. Mẫu này dùng purpose verify; các purpose khác xem Auth reference.

typescript
await client.auth.signUp({ email, password,
  redirect_url: "https://your-app.example/auth/callback" });

// Đầu trang callback, trước script theo dõi:
import { takeEmailAction } from "@whypik/js";
const action = takeEmailAction();
// Trong handler nút Xác nhận:
if (action?.purpose === "verify") await client.auth.verifyEmail(action.token);

Kết quả cần thấy:Email được xác minh; chưa coi đăng ký là đã đăng nhập.

5. Đăng nhập và đăng xuất

Bắt lỗi và hiển thị thông báo trên form. getUser hỏi server; getSession chỉ là trạng thái cục bộ.

typescript
await client.auth.signInWithPassword({ email, password });
const user = await client.auth.getUser();
const stop = client.auth.onAuthStateChange((event, session) => {
  // Cập nhật giao diện; xóa dữ liệu riêng khi user thay đổi/đăng xuất.
});
// Khi rời component: stop();
await client.auth.signOut();

Kết quả cần thấy:Đăng nhập bằng tài khoản đã xác minh và đăng xuất được.

6. Thêm Database và policy

Tạo hoặc nhập bảng notes. Bảng chưa có policy chỉ Admin truy cập. Để người thường đọc dữ liệu của họ, mở Quyền truy cập và tạo bộ quy tắc Xem, điều kiện Dòng của người đăng nhập, chọn bảng notes, cột owner_id và các cột được xem.

json
{
  "tables": [
    {
      "name": "notes",
      "columns": [
        {
          "name": "id",
          "type": "uuid",
          "primary": true,
          "default": {
            "kind": "uuid"
          }
        },
        {
          "name": "owner_id",
          "type": "uuid",
          "identity": "owner"
        },
        {
          "name": "title",
          "type": "text",
          "max_length": 4096
        }
      ],
      "policies": []
    }
  ]
}

Kết quả cần thấy:Admin truy cập dữ liệu; người thường chỉ thấy các dòng được bộ quy tắc cho phép.

7. Thử ghi, đọc và types

Trong API & SDK tải whypik-database.d.ts sau khi schema đã sẵn sàng; dùng WhyPik<WhyPikDatabase> nếu cần type checking. Gọi ghi/đọc với cùng client đã login. Dùng hai user để kiểm tra không đọc được ghi chú của nhau.

typescript
const me = await client.auth.getUser();
await client.from("notes").insert({ owner_id: me.id, title: "Ghi chú đầu tiên" });
const notes = await client.from("notes").limit(20).select("id", "title");
console.log(notes);

Kết quả cần thấy:Mỗi user chỉ thấy các dòng policy cho phép.

8. Chuyển sang phiên bền

Nếu deploy lên WhyPik Hosting/verified custom domain, dùng new WhyPik({project,key}) mặc định /.whypik/auth và /.whypik/data, cùng origin. Website ở nơi khác cần BFF cùng origin cho cookie bền; không bật cross-site persistent cookie tùy tiện. Bỏ memory mode chỉ khi proxy đã sẵn sàng.

Kết quả cần thấy:Reload giữ phiên trong chế độ cookie đã cấu hình; memory mode thì đăng nhập lại.

Trong bài này