|
|
@@ -1,4 +1,4 @@
|
|
|
-# API Basic Auth 认证指南
|
|
|
+# API Basic Auth 认证指南(Caddy 版本)
|
|
|
|
|
|
本文档说明外部服务器如何安全地调用本项目的 API 接口(已配置 Basic Auth)。
|
|
|
|
|
|
@@ -14,27 +14,32 @@
|
|
|
|
|
|
---
|
|
|
|
|
|
-## 配置方式
|
|
|
+## 配置 Basic Auth
|
|
|
|
|
|
-### 1. 设置环境变量
|
|
|
+### 1. 生成密码哈希
|
|
|
|
|
|
-在外部服务器的环境中设置以下变量:
|
|
|
+Caddy 使用 bcrypt 哈希格式存储密码。使用以下命令生成:
|
|
|
|
|
|
```bash
|
|
|
-# Basic Auth 用户名
|
|
|
-export BYREAL_API_USERNAME=admin
|
|
|
+# 使用 Docker 生成密码哈希(推荐)
|
|
|
+docker run --rm caddy:2-alpine caddy hash-password --plaintext 'your_password'
|
|
|
|
|
|
-# Basic Auth 密码
|
|
|
-export BYREAL_API_PASSWORD=your_password_here
|
|
|
+# 示例输出:
|
|
|
+# $2a$14$Z3Q7g2n8XQYuH9vJkLmNqOrStUvWxYzAbCdEfGhIjKlMnOpQrStUv
|
|
|
```
|
|
|
|
|
|
-或者在 `.env` 文件中(不要提交到 Git):
|
|
|
+### 2. 配置环境变量
|
|
|
+
|
|
|
+在服务器上的 `.env` 文件中添加:
|
|
|
|
|
|
```bash
|
|
|
-BYREAL_API_USERNAME=admin
|
|
|
-BYREAL_API_PASSWORD=your_password_here
|
|
|
+# Basic Auth 配置
|
|
|
+BASIC_AUTH_USER=admin
|
|
|
+BASIC_AUTH_HASH=$2a$14$Z3Q7g2n8XQYuH9vJkLmNqOrStUvWxYzAbCdEfGhIjKlMnOpQrStUv
|
|
|
```
|
|
|
|
|
|
+**注意**:将 `BASIC_AUTH_HASH` 替换为你实际生成的哈希值。
|
|
|
+
|
|
|
---
|
|
|
|
|
|
## 代码示例
|
|
|
@@ -52,8 +57,8 @@ const password = process.env.BYREAL_API_PASSWORD || ''
|
|
|
const credentials = Buffer.from(`${username}:${password}`).toString('base64')
|
|
|
const authHeader = `Basic ${credentials}`
|
|
|
|
|
|
-// 发送请求
|
|
|
-const response = await fetch('http://your-server-ip/api/my-lp', {
|
|
|
+// 发送请求(使用 HTTPS)
|
|
|
+const response = await fetch('https://love.hdlife.me/api/my-lp', {
|
|
|
method: 'GET',
|
|
|
headers: {
|
|
|
Authorization: authHeader,
|
|
|
@@ -72,7 +77,7 @@ import axios from 'axios'
|
|
|
const username = process.env.BYREAL_API_USERNAME || ''
|
|
|
const password = process.env.BYREAL_API_PASSWORD || ''
|
|
|
|
|
|
-const response = await axios.get('http://your-server-ip/api/my-lp', {
|
|
|
+const response = await axios.get('https://love.hdlife.me/api/my-lp', {
|
|
|
auth: {
|
|
|
username,
|
|
|
password,
|
|
|
@@ -85,7 +90,7 @@ const response = await axios.get('http://your-server-ip/api/my-lp', {
|
|
|
const data = response.data
|
|
|
```
|
|
|
|
|
|
-#### 使用 ky(类似你项目中的方式)
|
|
|
+#### 使用 ky
|
|
|
|
|
|
```typescript
|
|
|
import ky from 'ky'
|
|
|
@@ -95,7 +100,7 @@ const password = process.env.BYREAL_API_PASSWORD || ''
|
|
|
|
|
|
const credentials = Buffer.from(`${username}:${password}`).toString('base64')
|
|
|
|
|
|
-const response = await ky.get('http://your-server-ip/api/my-lp', {
|
|
|
+const response = await ky.get('https://love.hdlife.me/api/my-lp', {
|
|
|
headers: {
|
|
|
Authorization: `Basic ${credentials}`,
|
|
|
},
|
|
|
@@ -121,7 +126,7 @@ password = os.getenv('BYREAL_API_PASSWORD', '')
|
|
|
|
|
|
# 方式 1: 使用 HTTPBasicAuth(推荐)
|
|
|
response = requests.get(
|
|
|
- 'http://your-server-ip/api/my-lp',
|
|
|
+ 'https://love.hdlife.me/api/my-lp',
|
|
|
auth=HTTPBasicAuth(username, password),
|
|
|
headers={'Content-Type': 'application/json'}
|
|
|
)
|
|
|
@@ -135,7 +140,7 @@ headers = {
|
|
|
'Authorization': f'Basic {credentials}',
|
|
|
'Content-Type': 'application/json'
|
|
|
}
|
|
|
-response = requests.get('http://your-server-ip/api/my-lp', headers=headers)
|
|
|
+response = requests.get('https://love.hdlife.me/api/my-lp', headers=headers)
|
|
|
```
|
|
|
|
|
|
---
|
|
|
@@ -145,11 +150,11 @@ response = requests.get('http://your-server-ip/api/my-lp', headers=headers)
|
|
|
```bash
|
|
|
# 从环境变量读取
|
|
|
curl -u "${BYREAL_API_USERNAME}:${BYREAL_API_PASSWORD}" \
|
|
|
- http://your-server-ip/api/my-lp
|
|
|
+ https://love.hdlife.me/api/my-lp
|
|
|
|
|
|
# 或者直接指定(不推荐,密码会出现在命令历史中)
|
|
|
curl -u "admin:your_password" \
|
|
|
- http://your-server-ip/api/my-lp
|
|
|
+ https://love.hdlife.me/api/my-lp
|
|
|
```
|
|
|
|
|
|
---
|
|
|
@@ -173,7 +178,7 @@ func main() {
|
|
|
|
|
|
credentials := base64.StdEncoding.EncodeToString([]byte(username + ":" + password))
|
|
|
|
|
|
- req, _ := http.NewRequest("GET", "http://your-server-ip/api/my-lp", nil)
|
|
|
+ req, _ := http.NewRequest("GET", "https://love.hdlife.me/api/my-lp", nil)
|
|
|
req.Header.Set("Authorization", "Basic "+credentials)
|
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
|
|
@@ -211,7 +216,7 @@ public class ApiClient {
|
|
|
|
|
|
HttpClient client = HttpClient.newHttpClient();
|
|
|
HttpRequest request = HttpRequest.newBuilder()
|
|
|
- .uri(URI.create("http://your-server-ip/api/my-lp"))
|
|
|
+ .uri(URI.create("https://love.hdlife.me/api/my-lp"))
|
|
|
.header("Authorization", "Basic " + credentials)
|
|
|
.header("Content-Type", "application/json")
|
|
|
.GET()
|
|
|
@@ -248,29 +253,58 @@ services:
|
|
|
|
|
|
---
|
|
|
|
|
|
+## 部署步骤
|
|
|
+
|
|
|
+### 1. 配置环境变量
|
|
|
+
|
|
|
+在服务器上创建 `.env` 文件:
|
|
|
+
|
|
|
+```bash
|
|
|
+# Solana 配置
|
|
|
+SOL_ENDPOINT=your_solana_endpoint
|
|
|
+SOL_SECRET_KEY=your_secret_key
|
|
|
+
|
|
|
+# Basic Auth 配置
|
|
|
+BASIC_AUTH_USER=admin
|
|
|
+BASIC_AUTH_HASH=$2a$14$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
|
+```
|
|
|
+
|
|
|
+### 2. 启动服务
|
|
|
+
|
|
|
+```bash
|
|
|
+docker compose down
|
|
|
+docker compose up -d
|
|
|
+```
|
|
|
+
|
|
|
+### 3. 验证 HTTPS
|
|
|
+
|
|
|
+访问 `https://love.hdlife.me`,应该会自动跳转到 HTTPS 并要求 Basic Auth。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
## 安全最佳实践
|
|
|
|
|
|
1. ✅ **使用环境变量**:永远不要在代码中硬编码密码
|
|
|
2. ✅ **使用 `.gitignore`**:确保包含密码的 `.env` 文件不会被提交
|
|
|
3. ✅ **使用密钥管理服务**:生产环境推荐使用 AWS Secrets Manager、Azure Key Vault 等
|
|
|
4. ✅ **定期轮换密码**:定期更换 Basic Auth 密码
|
|
|
-5. ✅ **使用 HTTPS**:生产环境必须使用 HTTPS(当前是 HTTP,仅用于开发/内网)
|
|
|
-6. ✅ **限制访问 IP**:在 Nginx 中配置 `allow/deny` 限制允许访问的 IP
|
|
|
+5. ✅ **使用 HTTPS**:Caddy 自动配置 HTTPS,无需额外操作
|
|
|
+6. ✅ **限制访问 IP**:在服务器防火墙中限制允许的 IP
|
|
|
7. ✅ **最小权限原则**:只为需要的服务提供凭证
|
|
|
|
|
|
---
|
|
|
|
|
|
## 测试连接
|
|
|
|
|
|
-使用 curl 测试 Basic Auth 是否配置正确:
|
|
|
+使用 curl 测试 Basic Auth 和 HTTPS:
|
|
|
|
|
|
```bash
|
|
|
# 测试(会提示输入密码)
|
|
|
-curl -u admin http://your-server-ip/api/my-lp
|
|
|
+curl -u admin https://love.hdlife.me/api/my-lp
|
|
|
|
|
|
# 或者从环境变量读取
|
|
|
curl -u "${BYREAL_API_USERNAME}:${BYREAL_API_PASSWORD}" \
|
|
|
- http://your-server-ip/api/my-lp
|
|
|
+ https://love.hdlife.me/api/my-lp
|
|
|
```
|
|
|
|
|
|
如果返回 401 Unauthorized,说明凭证错误;如果返回 200 或其他业务状态码,说明认证成功。
|
|
|
@@ -281,31 +315,41 @@ curl -u "${BYREAL_API_USERNAME}:${BYREAL_API_PASSWORD}" \
|
|
|
|
|
|
### Q: 如何获取 Basic Auth 凭证?
|
|
|
|
|
|
-A: 联系项目管理员获取用户名和密码。密码存储在服务器的 `htpasswd` 文件中。
|
|
|
+A: 联系项目管理员获取用户名和密码。密码哈希存储在服务器的 `.env` 文件中。
|
|
|
|
|
|
### Q: 密码忘记了怎么办?
|
|
|
|
|
|
-A: 在服务器上重新生成:
|
|
|
+A: 在服务器上重新生成哈希并更新 `.env` 文件:
|
|
|
|
|
|
```bash
|
|
|
-htpasswd ./htpasswd admin
|
|
|
-# 输入新密码
|
|
|
+# 生成新密码哈希
|
|
|
+docker run --rm caddy:2-alpine caddy hash-password --plaintext 'new_password'
|
|
|
+
|
|
|
+# 更新 .env 文件中的 BASIC_AUTH_HASH
|
|
|
+# 然后重启服务
|
|
|
+docker compose restart caddy
|
|
|
```
|
|
|
|
|
|
-然后重启 Docker 容器:
|
|
|
+### Q: 如何查看 Caddy 日志?
|
|
|
+
|
|
|
+A:
|
|
|
|
|
|
```bash
|
|
|
-docker compose restart nginx
|
|
|
+# 查看 Caddy 容器日志
|
|
|
+docker logs byreal-caddy
|
|
|
+
|
|
|
+# 查看访问日志(如果在 Caddyfile 中配置了日志文件)
|
|
|
+docker exec byreal-caddy cat /var/log/caddy/access.log
|
|
|
```
|
|
|
|
|
|
-### Q: 如何在生产环境使用 HTTPS?
|
|
|
+### Q: HTTPS 证书如何续期?
|
|
|
|
|
|
-A: 需要配置 SSL 证书,修改 `nginx.conf` 添加 SSL 配置,并更新 `docker-compose.yml` 映射 443 端口。
|
|
|
+A: Caddy 会自动管理 Let's Encrypt 证书的续期,无需手动操作。
|
|
|
|
|
|
---
|
|
|
|
|
|
## 相关文件
|
|
|
|
|
|
-- `nginx.conf` - Nginx Basic Auth 配置
|
|
|
-- `htpasswd` - Basic Auth 密码文件(不提交到 Git)
|
|
|
+- `Caddyfile` - Caddy HTTPS + Basic Auth 配置
|
|
|
- `docker-compose.yml` - Docker 服务配置
|
|
|
+- `.env` - 环境变量配置(不提交到 Git)
|