Multi-language Documentation | 多语言文档
Quick navigation | 快速导航:
sa-token-rust provides a complete Single Sign-On (SSO) solution based on ticket authentication. Users only need to log in once to access multiple applications seamlessly.
- 🎫 Ticket-based Authentication: Secure, one-time use tickets
- 🔐 Unified Login: Log in once, access all applications
- 🚪 Unified Logout: Log out from all applications at once
- 🌐 Cross-domain Support: Configurable origin whitelist
- ⏱️ Ticket Expiration: Automatic ticket expiration and cleanup
- 🛡️ Security Protection: Service URL matching, replay attack prevention
- 🔄 Session Management: Track all logged-in applications
- 🔑 Token Type Isolation: SSO server and client tokens are isolated by
login_type - 📊 Enhanced Token Info: SSO context stored in token
extra_datafor traceability
The SSO Server is the central authentication service that:
- Manages user authentication
- Generates and validates tickets
- Maintains global session state
- Handles unified logout
- Tracks active client applications
Each application acts as an SSO Client that:
- Checks local login status
- Generates login/logout URLs
- Validates tickets from SSO Server
- Creates local sessions
- Handles logout callbacks
A ticket is a short-lived, one-time use authentication token that contains:
ticket_id: Unique ticket identifier (UUID)service: Target application URLlogin_id: User identifiercreate_time: Ticket creation timeexpire_time: Ticket expiration timeused: Usage status flag
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ User │ │ SSO Server │ │ Client │
│ Browser │ │ (Auth) │ │ App 1 │
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
│ │ │
│ 1. Access App 1 │ │
├───────────────────────┼──────────────────────>│
│ │ │
│ 2. Redirect to SSO │ │
│<──────────────────────┼───────────────────────┤
│ │ │
│ 3. Login Request │ │
├──────────────────────>│ │
│ │ │
│ 4. Create Ticket │ │
│<──────────────────────┤ │
│ │ │
│ 6. Callback with Ticket │
├───────────────────────┼──────────────────────>│
│ │ │
│ 7. Validate Ticket │ │
│ │<──────────────────────┤
│ │ │
│ 8. Ticket Valid │ │
│ ├──────────────────────>│
│ │ │
│ 9. Create Local Session │
│ 10. Access Granted │ │
│<──────────────────────┼───────────────────────┤
use std::sync::Arc;
use sa_token_core::{SaTokenConfig, SsoServer, SsoClient};
use sa_token_storage_memory::MemoryStorage;
let manager = SaTokenConfig::builder()
.storage(Arc::new(MemoryStorage::new()))
.timeout(7200)
.build();
let manager = Arc::new(manager);let sso_server = Arc::new(
SsoServer::new(manager.clone())
.with_ticket_timeout(300) // 5 minutes
);let client1 = Arc::new(SsoClient::new(
manager.clone(),
"http://sso.example.com/auth".to_string(),
"http://app1.example.com".to_string(),
));let ticket = sso_server.login(
"user_123".to_string(),
"http://app1.example.com".to_string(),
).await?;let login_id = sso_server.validate_ticket(
&ticket.ticket_id,
"http://app1.example.com",
).await?;let token = client1.login_by_ticket(login_id).await?;let clients = sso_server.logout("user_123").await?;
for client_url in clients {
// Notify each client to logout
}
client1.handle_logout("user_123").await?;
client2.handle_logout("user_123").await?;1. One-time Ticket Usage
// First validation - succeeds
sso_server.validate_ticket(&ticket_id, service).await?;
// Second validation - fails (ticket already used)
sso_server.validate_ticket(&ticket_id, service).await?; // Error!2. Service URL Matching
// Ticket for App1 cannot be used for App2
sso_server.validate_ticket(&ticket_id, "wrong_service").await?; // ServiceMismatch!use sa_token_core::SaTokenError;
match sso_server.validate_ticket(ticket_id, service).await {
Ok(login_id) => println!("Valid: {}", login_id),
Err(SaTokenError::InvalidTicket) => println!("Ticket not found"),
Err(SaTokenError::TicketExpired) => println!("Ticket expired"),
Err(SaTokenError::ServiceMismatch) => println!("Service mismatch"),
Err(e) => println!("Other error: {}", e),
}SsoServer Methods:
new(manager)- Create new SSO Serverwith_ticket_timeout(seconds)- Set ticket expiration timelogin(login_id, service)- User login and generate ticketcreate_ticket(login_id, service)- Create ticket for logged-in uservalidate_ticket(ticket_id, service)- Validate and consume ticketlogout(login_id)- Unified logoutis_logged_in(login_id)- Check if user is logged inget_session(login_id)- Get user's SSO sessionget_active_clients(login_id)- Get list of active clientscleanup_expired_tickets()- Clean up expired tickets
SsoClient Methods:
new(manager, server_url, service_url)- Create new SSO Clientwith_logout_callback(callback)- Set logout callbackget_login_url()- Generate login URLget_logout_url()- Generate logout URLcheck_local_login(login_id)- Check local sessionlogin_by_ticket(login_id)- Create local sessionhandle_logout(login_id)- Handle logout request
See sso_example.rs for a complete working example.
Run the example:
cargo run --example sso_examplesa-token-rust 提供了基于票据认证的完整单点登录(SSO)解决方案。用户只需登录一次即可无缝访问多个应用程序。
- 🎫 票据认证:安全的一次性使用票据
- 🔐 统一登录:一次登录,访问所有应用
- 🚪 统一登出:一次登出,退出所有应用
- 🌐 跨域支持:可配置的域名白名单
- ⏱️ 票据过期:自动票据过期和清理
- 🛡️ 安全保护:服务URL匹配、防重放攻击
- 🔄 会话管理:跟踪所有已登录应用
SSO 服务端是中央认证服务,负责:
- 管理用户认证
- 生成和验证票据
- 维护全局会话状态
- 处理统一登出
- 跟踪活跃客户端应用
每个应用程序作为 SSO 客户端,负责:
- 检查本地登录状态
- 生成登录/登出 URL
- 验证来自 SSO 服务端的票据
- 创建本地会话
- 处理登出回调
票据是一个短期、一次性使用的认证令牌,包含:
ticket_id:唯一票据标识符(UUID)service:目标应用 URLlogin_id:用户标识create_time:票据创建时间expire_time:票据过期时间used:使用状态标记
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 用户 │ │ SSO 服务端 │ │ 客户端 │
│ 浏览器 │ │ (认证) │ │ 应用 1 │
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
│ │ │
│ 1. 访问应用 1 │ │
├───────────────────────┼──────────────────────>│
│ │ │
│ 2. 重定向到 SSO │ │
│<──────────────────────┼───────────────────────┤
│ │ │
│ 3. 登录请求 │ │
├──────────────────────>│ │
│ │ │
│ 4. 创建票据 │ │
│<──────────────────────┤ │
│ │ │
│ 6. 带票据回调 │
├───────────────────────┼──────────────────────>│
│ │ │
│ 7. 验证票据 │ │
│ │<──────────────────────┤
│ │ │
│ 8. 票据有效 │ │
│ ├──────────────────────>│
│ │ │
│ 9. 创建本地会话 │
│ 10. 授予访问权限 │ │
│<──────────────────────┼───────────────────────┤
use std::sync::Arc;
use sa_token_core::{SaTokenConfig, SsoServer, SsoClient};
use sa_token_storage_memory::MemoryStorage;
let manager = SaTokenConfig::builder()
.storage(Arc::new(MemoryStorage::new()))
.timeout(7200)
.build();
let manager = Arc::new(manager);let sso_server = Arc::new(
SsoServer::new(manager.clone())
.with_ticket_timeout(300) // 5 分钟
);let client1 = Arc::new(SsoClient::new(
manager.clone(),
"http://sso.example.com/auth".to_string(),
"http://app1.example.com".to_string(),
));let ticket = sso_server.login(
"user_123".to_string(),
"http://app1.example.com".to_string(),
).await?;let login_id = sso_server.validate_ticket(
&ticket.ticket_id,
"http://app1.example.com",
).await?;let token = client1.login_by_ticket(login_id).await?;let clients = sso_server.logout("user_123").await?;
for client_url in clients {
// 通知每个客户端登出
}
client1.handle_logout("user_123").await?;
client2.handle_logout("user_123").await?;1. 一次性票据使用
// 第一次验证 - 成功
sso_server.validate_ticket(&ticket_id, service).await?;
// 第二次验证 - 失败(票据已使用)
sso_server.validate_ticket(&ticket_id, service).await?; // 错误!2. 服务 URL 匹配
// 应用1的票据不能用于应用2
sso_server.validate_ticket(&ticket_id, "wrong_service").await?; // ServiceMismatch!use sa_token_core::SaTokenError;
match sso_server.validate_ticket(ticket_id, service).await {
Ok(login_id) => println!("有效: {}", login_id),
Err(SaTokenError::InvalidTicket) => println!("票据未找到"),
Err(SaTokenError::TicketExpired) => println!("票据已过期"),
Err(SaTokenError::ServiceMismatch) => println!("服务不匹配"),
Err(e) => println!("其他错误: {}", e),
}SsoServer 方法:
new(manager)- 创建新的 SSO Serverwith_ticket_timeout(seconds)- 设置票据过期时间login(login_id, service)- 用户登录并生成票据create_ticket(login_id, service)- 为已登录用户创建票据validate_ticket(ticket_id, service)- 验证并消费票据logout(login_id)- 统一登出is_logged_in(login_id)- 检查用户是否已登录get_session(login_id)- 获取用户的 SSO 会话get_active_clients(login_id)- 获取活跃客户端列表cleanup_expired_tickets()- 清理过期票据
SsoClient 方法:
new(manager, server_url, service_url)- 创建新的 SSO Clientwith_logout_callback(callback)- 设置登出回调get_login_url()- 生成登录 URLget_logout_url()- 生成登出 URLcheck_local_login(login_id)- 检查本地会话login_by_ticket(login_id)- 创建本地会话handle_logout(login_id)- 处理登出请求
查看 sso_example.rs 获取完整的工作示例。
运行示例:
cargo run --example sso_examplesa-token-rust ให้บริการโซลูชัน Single Sign-On (SSO) แบบสมบูรณ์โดยใช้การตรวจสอบสิทธิ์แบบตั๋ว
- 🎫 การตรวจสอบสิทธิ์แบบตั๋ว: ตั๋วที่ปลอดภัย ใช้ได้ครั้งเดียว
- 🔐 เข้าสู่ระบบแบบรวม: เข้าสู่ระบบครั้งเดียว เข้าถึงทุกแอปพลิเคชัน
- 🚪 ออกจากระบบแบบรวม: ออกจากระบบทุกแอปพลิเคชันพร้อมกัน
- 🌐 รองรับ Cross-domain: รายการอนุญาต origin ที่กำหนดได้
- ⏱️ ตั๋วหมดอายุ: ตั๋วหมดอายุและทำความสะอาดอัตโนมัติ
// สร้าง SSO Server
let sso_server = Arc::new(
SsoServer::new(manager.clone())
.with_ticket_timeout(300)
);
// สร้าง SSO Client
let client = Arc::new(SsoClient::new(
manager.clone(),
"http://sso.example.com/auth".to_string(),
"http://app1.example.com".to_string(),
));
// ผู้ใช้เข้าสู่ระบบ
let ticket = sso_server.login("user_123".to_string(), service).await?;
// ตรวจสอบตั๋ว
let login_id = sso_server.validate_ticket(&ticket.ticket_id, service).await?;
// สร้าง session ในเครื่อง
let token = client.login_by_ticket(login_id).await?;let clients = sso_server.logout("user_123").await?;
for client_url in clients {
// แจ้งเตือน client ให้ออกจากระบบ
}cargo run --example sso_examplesa-token-rust cung cấp giải pháp Single Sign-On (SSO) hoàn chỉnh dựa trên xác thực vé.
- 🎫 Xác thực dựa trên vé: Vé an toàn, sử dụng một lần
- 🔐 Đăng nhập thống nhất: Đăng nhập một lần, truy cập tất cả ứng dụng
- 🚪 Đăng xuất thống nhất: Đăng xuất khỏi tất cả ứng dụng cùng lúc
- 🌐 Hỗ trợ Cross-domain: Danh sách trắng origin có thể cấu hình
- ⏱️ Vé hết hạn: Tự động hết hạn và dọn dẹp vé
// Tạo SSO Server
let sso_server = Arc::new(
SsoServer::new(manager.clone())
.with_ticket_timeout(300)
);
// Tạo SSO Client
let client = Arc::new(SsoClient::new(
manager.clone(),
"http://sso.example.com/auth".to_string(),
"http://app1.example.com".to_string(),
));
// Người dùng đăng nhập
let ticket = sso_server.login("user_123".to_string(), service).await?;
// Xác thực vé
let login_id = sso_server.validate_ticket(&ticket.ticket_id, service).await?;
// Tạo session cục bộ
let token = client.login_by_ticket(login_id).await?;let clients = sso_server.logout("user_123").await?;
for client_url in clients {
// Thông báo cho mỗi client đăng xuất
}cargo run --example sso_examplesa-token-rust ផ្តល់ដំណោះស្រាយ Single Sign-On (SSO) ពេញលេញដោយផ្អែកលើការផ្ទៀងផ្ទាត់សំបុត្រ
- 🎫 ការផ្ទៀងផ្ទាត់ដោយផ្អែកលើសំបុត្រ: សំបុត្រសុវត្ថិភាព ប្រើម្តង
- 🔐 ការចូលរួមបញ្ចូលគ្នា: ចូលម្តង ចូលដំណើរការកម្មវិធីទាំងអស់
- 🚪 ការចេញរួមបញ្ចូលគ្នា: ចេញពីកម្មវិធីទាំងអស់ក្នុងពេលតែមួយ
- 🌐 ការគាំទ្រ Cross-domain: បញ្ជីអនុញ្ញាត origin អាចកំណត់បាន
- ⏱️ ការផុតកំណត់សំបុត្រ: សំបុត្រផុតកំណត់និងសម្អាតដោយស្វ័យប្រវត្តិ
// បង្កើត SSO Server
let sso_server = Arc::new(
SsoServer::new(manager.clone())
.with_ticket_timeout(300)
);
// បង្កើត SSO Client
let client = Arc::new(SsoClient::new(
manager.clone(),
"http://sso.example.com/auth".to_string(),
"http://app1.example.com".to_string(),
));
// អ្នកប្រើប្រាស់ចូល
let ticket = sso_server.login("user_123".to_string(), service).await?;
// ផ្ទៀងផ្ទាត់សំបុត្រ
let login_id = sso_server.validate_ticket(&ticket.ticket_id, service).await?;
// បង្កើត session ក្នុងតំបន់
let token = client.login_by_ticket(login_id).await?;let clients = sso_server.logout("user_123").await?;
for client_url in clients {
// ជូនដំណឹង client នីមួយៗឱ្យចេញ
}cargo run --example sso_examplesa-token-rust menyediakan penyelesaian Single Sign-On (SSO) lengkap berdasarkan pengesahan tiket.
- 🎫 Pengesahan Berasaskan Tiket: Tiket selamat, guna sekali
- 🔐 Log Masuk Bersatu: Log masuk sekali, akses semua aplikasi
- 🚪 Log Keluar Bersatu: Log keluar dari semua aplikasi sekaligus
- 🌐 Sokongan Cross-domain: Senarai putih origin boleh dikonfigurasi
- ⏱️ Tamat Tempoh Tiket: Tiket tamat tempoh dan pembersihan automatik
// Cipta SSO Server
let sso_server = Arc::new(
SsoServer::new(manager.clone())
.with_ticket_timeout(300)
);
// Cipta SSO Client
let client = Arc::new(SsoClient::new(
manager.clone(),
"http://sso.example.com/auth".to_string(),
"http://app1.example.com".to_string(),
));
// Pengguna log masuk
let ticket = sso_server.login("user_123".to_string(), service).await?;
// Sahkan tiket
let login_id = sso_server.validate_ticket(&ticket.ticket_id, service).await?;
// Cipta session tempatan
let token = client.login_by_ticket(login_id).await?;let clients = sso_server.logout("user_123").await?;
for client_url in clients {
// Beritahu setiap client untuk log keluar
}cargo run --example sso_examplesa-token-rust သည် လက်မှတ်အခြေခံ စစ်မှန်ကြောင်းထောက်ခံချက်ဖြင့် Single Sign-On (SSO) အပြည့်အစုံကို ပံ့ပိုးပေးသည်။
- 🎫 လက်မှတ်အခြေခံ စစ်မှန်ကြောင်းထောက်ခံချက်: လုံခြုံသော တစ်ကြိမ်သုံး လက်မှတ်များ
- 🔐 ပေါင်းစည်း login: တစ်ကြိမ် login ဝင်ပြီး application အားလုံးကို အသုံးပြု
- 🚪 ပေါင်းစည်း logout: application အားလုံးမှ တစ်ပြိုင်နက် logout ထွက်
- 🌐 Cross-domain ပံ့ပိုးမှု: ပြင်ဆင်နိုင်သော origin ခွင့်ပြုစာရင်း
- ⏱️ လက်မှတ်သက်တမ်းကုန်: အလိုအလျောက် လက်မှတ်သက်တမ်းကုန်နှင့် သန့်ရှင်းရေး
// SSO Server ဖန်တီးခြင်း
let sso_server = Arc::new(
SsoServer::new(manager.clone())
.with_ticket_timeout(300)
);
// SSO Client ဖန်တီးခြင်း
let client = Arc::new(SsoClient::new(
manager.clone(),
"http://sso.example.com/auth".to_string(),
"http://app1.example.com".to_string(),
));
// အသုံးပြုသူ login ဝင်ခြင်း
let ticket = sso_server.login("user_123".to_string(), service).await?;
// လက်မှတ် စစ်ဆေးခြင်း
let login_id = sso_server.validate_ticket(&ticket.ticket_id, service).await?;
// ဒေသန္တရ session ဖန်တီးခြင်း
let token = client.login_by_ticket(login_id).await?;let clients = sso_server.logout("user_123").await?;
for client_url in clients {
// client တစ်ခုစီကို logout ရန် အကြောင်းကြားပါ
}cargo run --example sso_exampleVersion: 0.1.13
Last Updated: 2025-01-15