Tích hợp đăng nhập (SSO)
Cho phép người dùng đã đăng nhập ở hệ thống của bạn vào thẳng khung chat mà không phải đăng nhập lại.
1. Cách hoạt động
Người dùng đã đăng nhập trên hệ thống của bạn thì không cần đăng nhập lại ở khung chat. Backend của bạn đứng ra xác nhận danh tính người dùng với RM Platform, và nền tảng cấp cho họ một phiên đăng nhập tương ứng:
- Backend của bạn ký một chứng thực danh tính (identity assertion — một JWT có chữ ký) cho người dùng đang đăng nhập.
- RM Platform xác minh chữ ký, xác định đúng người dùng, rồi cấp một session token riêng.
- Khung chat dùng session token này để trò chuyện.
Về bản chất, đây là federated authentication theo mô hình JWT Bearer assertion (RFC 7523) của OAuth 2.0 — an toàn và phổ biến. Bạn chỉ cần làm theo các bước bên dưới.
2. Hai URL cần phân biệt
Có hai phía trong tích hợp:
- PLATFORM_URL — nền tảng Simplize, ví dụ
https://app.simplize.dev. Khi dùng khung nhúng sẵn, mọi đường dẫn ở phía này (đổi token, làm mới phiên, gửi tin nhắn, tải khung chat…) đều do khung chat tự lo — bạn không phải gọi. - URL ứng dụng của bạn — backend của bạn, ví dụ
https://your-app.com. Đây là nơi bạn tự viết endpoint.
Endpoint site của bạn phải gọi
| Endpoint (ví dụ) | Công dụng | Bắt buộc |
|---|---|---|
GET /agent-assertion | Ký và trả về identity assertion (JWT) cho người dùng đang đăng nhập ở hệ thống của bạn | Có |
Với khung nhúng sẵn, đây là endpoint duy nhất site của bạn cần gọi — khung chat lo phần còn lại. Tích hợp trực tiếp qua API (tự dựng giao diện) sẽ được cập nhật sau (sắp có).
Endpoint phát assertion nằm ở backend của bạn. Mọi đường dẫn còn lại đều nằm ở PLATFORM_URL.
3. Luồng tổng quan
Người dùng (đã đăng nhập ở hệ thống của bạn)
│
▼
[1] Khung chat nhúng sẵn khởi động, yêu cầu danh tính
│
▼
[2] Site của bạn lấy assertion ──► GET {YOUR_APP_URL}/agent-assertion
│ (backend ký assertion JWT bằng client_secret)
▼ truyền assertion vào khung chat (setIdentityToken / postMessage / URL)
┌───────────────────────────────────────────────────┐
│ Khung chat tự xử lý phần còn lại: │
│ • đổi assertion lấy session token trên PLATFORM_URL│
│ • hiển thị hội thoại, làm mới phiên khi cần │
└───────────────────────────────────────────────────┘
Khóa bí mật client_secret chỉ tồn tại ở server — site chỉ giữ assertion đã ký nên không thể giả mạo danh tính. Access token của ứng dụng chat là định danh công khai, chỉ để chọn đúng ứng dụng, không tham gia luồng xác thực.
4. Các bước tích hợp
Tạo connection ở Portal
Vào Cài đặt → Tích hợp xác thực → Tạo kết nối. Hệ thống cấp một cặp credential:
| Trường | Mô tả | Lưu trữ |
|---|---|---|
client_id | Định danh connection (công khai) | Có thể để ở FE |
client_secret | Khóa ký assertion | Chỉ ở server |
Trên môi trường Development, Simplize sẽ cấp và gửi lại cặp client_id / client_secret cho bạn — bạn không cần tự tạo connection.
Cấu hình ở hệ thống của bạn
Lưu client_secret ở phía server (biến môi trường hoặc secret manager) — không commit vào mã nguồn hay nhúng vào FE. Lưu kèm URL nền tảng, client_id, và access token của ứng dụng (công khai).
Phát identity assertion
Tạo một endpoint nội bộ (yêu cầu người dùng đã đăng nhập) để ký một JWT ngắn hạn bằng client_secret, mang thông tin của người dùng hiện tại:
{
"user_id": "45",
"email": "user@example.com",
"name": "Nguyễn Văn A",
"iat": 1700000000,
"exp": 1700000300
}
Ký bằng HS256, khóa là client_secret, thời hạn ngắn (khuyến nghị 5 phút). Trả assertion về cho FE khi được yêu cầu.
- Node.js
- Python
- Java
const jwt = require('jsonwebtoken');
app.get('/agent-assertion', requireLogin, (req, res) => {
const token = jwt.sign(
{ user_id: req.user.id, email: req.user.email, name: req.user.name },
process.env.CLIENT_SECRET,
{ algorithm: 'HS256', expiresIn: '5m' },
);
res.json({ jwt: token });
});
import os, time, jwt
@app.get("/agent-assertion")
@login_required
def agent_assertion():
token = jwt.encode(
{"user_id": current_user.id, "email": current_user.email,
"name": current_user.name, "exp": int(time.time()) + 300},
os.environ["CLIENT_SECRET"], algorithm="HS256",
)
return {"jwt": token}
@GetMapping("/agent-assertion")
public Map<String, String> assertion(@AuthenticationPrincipal User user) {
String token = Jwts.builder()
.claim("user_id", user.getId())
.claim("email", user.getEmail())
.claim("name", user.getName())
.expiration(new Date(System.currentTimeMillis() + 300000))
.signWith(Keys.hmacShaKeyFor(System.getenv("CLIENT_SECRET").getBytes()))
.compact();
return Map.of("jwt", token);
}
Truyền assertion vào khung chat
Đưa assertion vừa phát cho khung chat nhúng sẵn — khung chat tự đổi lấy session token và hiển thị hội thoại. Bạn không cần gọi thêm endpoint nào của RM Platform.
Cách truyền assertion cho bong bóng, iframe và link trực tiếp được hướng dẫn đầy đủ tại Nhúng vào trang web → Tự động đăng nhập — không cần lặp lại ở đây.
5. Bảo mật
client_secretchỉ ở server — không đưa xuống FE dưới bất kỳ dạng nào.client_idvà access token là định danh công khai — lộ cũng không thể ký giả assertion.- Assertion thời hạn ngắn; access token thời hạn ngắn kèm refresh token rotation.
- Endpoint phát assertion phải yêu cầu đăng nhập — mỗi người chỉ phát assertion cho chính mình.
7. Mã lỗi
| HTTP | Ý nghĩa | Cách xử lý |
|---|---|---|
| 401 | Assertion sai chữ ký / hết hạn, hoặc client_id không khớp | Đảm bảo client_secret hai bên trùng nhau; ký assertion mới |
| 403 | Session token không thuộc workspace của ứng dụng | Dùng connection của workspace chứa ứng dụng |
| 404 | Ứng dụng chưa bật chia sẻ hoặc chưa publish | Bật chia sẻ và publish ứng dụng trước |