privchat_protocol/rpc/auth.rs
1// Copyright 2025 Shanghai Boyu Information Technology Co., Ltd.
2// https://privchat.dev
3//
4// Author: zoujiaqing <zoujiaqing@gmail.com>
5//
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18use crate::protocol::DeviceInfo;
19/// 认证相关 RPC
20use serde::{Deserialize, Serialize};
21
22/// 登录请求
23///
24/// RPC路由: `account/auth/login`
25///
26/// 安全要求:
27/// - device_id: **必须提供**,用于设备绑定和防止 token 复制
28/// - device_info: 设备详细信息,用于设备管理和安全审计
29///
30/// JWT Token 会绑定 device_id,验证时会检查:
31/// - token 中的 device_id 必须匹配请求中的 device_id
32/// - 切换设备必须重新登录
33/// - 防止 token 被复制到其他设备使用
34#[derive(Debug, Clone, Serialize, Deserialize)]
35pub struct AuthLoginRequest {
36 /// 用户名或手机号或邮箱
37 pub username: String,
38
39 /// 密码
40 pub password: String,
41
42 /// 设备ID(**必需**,用于设备绑定和 token 验证)
43 ///
44 /// 安全说明:
45 /// - 每个设备应有唯一的 device_id(建议使用 UUID)
46 /// - JWT token 会绑定此 device_id
47 /// - 切换设备必须重新登录
48 /// - 防止账号认证信息被复刻到其他设备
49 pub device_id: String,
50
51 /// 设备信息(可选,用于设备管理和安全审计)
52 #[serde(skip_serializing_if = "Option::is_none")]
53 pub device_info: Option<DeviceInfo>,
54}
55
56/// 用户注册请求
57///
58/// RPC路由: `account/user/register`
59///
60/// 安全要求:
61/// - device_id: **必须提供**,注册时自动登录并绑定设备
62/// - device_info: 设备详细信息,用于设备管理和安全审计
63///
64/// 注册成功后自动在当前设备登录,返回绑定此设备的 JWT token
65#[derive(Debug, Clone, Serialize, Deserialize)]
66pub struct UserRegisterRequest {
67 /// 用户名
68 pub username: String,
69
70 /// 密码
71 pub password: String,
72
73 /// 设备ID(**必需**,注册后自动登录并绑定此设备)
74 ///
75 /// 安全说明:
76 /// - 注册成功后自动在此设备登录
77 /// - JWT token 会绑定此 device_id
78 /// - 其他设备需要单独登录
79 /// - 防止注册后 token 被复制到其他设备
80 pub device_id: String,
81
82 /// 昵称(可选)
83 #[serde(skip_serializing_if = "Option::is_none")]
84 pub nickname: Option<String>,
85
86 /// 手机号(可选)
87 #[serde(skip_serializing_if = "Option::is_none")]
88 pub phone: Option<String>,
89
90 /// 邮箱(可选)
91 #[serde(skip_serializing_if = "Option::is_none")]
92 pub email: Option<String>,
93
94 /// 设备信息(可选,用于设备管理和安全审计)
95 #[serde(skip_serializing_if = "Option::is_none")]
96 pub device_info: Option<DeviceInfo>,
97}
98
99/// 认证响应(登录和注册统一返回结构)
100///
101/// RPC路由: `account/auth/login`, `account/user/register`
102///
103/// 注册成功或登录成功后都返回此结构,包含绑定设备的 JWT token
104/// 客户端可以直接使用 token 进行 AuthorizationRequest
105///
106/// JWT Token 安全说明:
107/// - token 包含 user_id 和 device_id
108/// - 验证时会检查请求的 device_id 是否匹配 token 中的 device_id
109/// - 切换设备必须重新登录获取新 token
110/// - 防止 token 被复制到其他设备使用
111#[derive(Debug, Clone, Serialize, Deserialize)]
112pub struct AuthResponse {
113 /// 用户ID
114 pub user_id: u64,
115
116 /// JWT Token(用于 AuthorizationRequest,绑定设备)
117 ///
118 /// Token payload 包含:
119 /// - user_id: 用户ID
120 /// - device_id: 设备ID(用于验证)
121 /// - exp: 过期时间
122 /// - iat: 签发时间
123 pub token: String,
124
125 /// Refresh Token(用于刷新 token,同样绑定设备)
126 pub refresh_token: Option<String>,
127
128 /// Token 过期时间(RFC3339 格式)
129 pub expires_at: String,
130
131 /// 绑定的设备ID(返回给客户端确认)
132 ///
133 /// 客户端应保存此 device_id,后续所有请求都需要携带
134 pub device_id: String,
135}