moodist/src/pages/api/auth/register.ts
zl 010fb9674b feat: 重构音乐列表UI与JWT认证完整实现 v2.7.0
## 🎯 核心功能重构

### 音乐列表显示优化
- **自动展示**: 登录用户页面打开时自动显示音乐列表,无需手动展开
- **权限控制**: 未登录用户完全隐藏"我的音乐"部分
- **独立展开**: 每个音乐项配备独立的展开/收起按钮
- **渐进展示**: 点击展开按钮显示音乐收录的声音详情

### JWT认证系统完整实现
- **安全升级**: 完全替代密码传输,实现JWT令牌认证
- **自动管理**: 登录时自动生成和存储JWT令牌
- **API集成**: 所有音乐相关API统一使用JWT认证
- **容错机制**: 多层级token获取策略确保认证稳定性

## 🔧 技术架构升级

### 新增核心模块
- `src/lib/jwt.ts` - JWT令牌创建与验证核心
- `src/lib/jwt-auth-middleware.ts` - JWT认证中间件
- `src/lib/api-client.ts` - 自动JWT令牌注入的API客户端
- `src/hooks/useNotification.ts` - 统一通知系统

### 组件化重构
- `src/components/buttons/save-music/` - 音乐保存按钮组件
- `src/components/buttons/delete-music/` - 音乐删除按钮组件
- `src/components/notification/` - 通知组件系统

### API安全强化
- 所有认证相关API集成JWT中间件
- 用户注册/登录自动返回JWT令牌
- 音乐CRUD操作统一JWT认证验证

## 🎨 用户体验优化

### 交互流程简化
- 登录即见:音乐列表自动展示,减少用户操作步骤
- 按需展开:声音详情按需显示,避免信息过载
- 状态持久:JWT令牌自动管理,无需重复登录

### 视觉层次优化
- 音乐名称与展开按钮并排布局,提升操作便利性
- 声音列表折叠显示,保持界面整洁
- 统一通知样式,确保视觉一致性

## 🛡️ 安全性提升

- **零密码传输**: API请求完全移除明文密码传输
- **令牌过期**: JWT令牌7天自动过期机制
- **状态隔离**: 认证状态与业务状态完全分离

版本: v2.7.0
技术栈: React + TypeScript + Astro + SQLite + JWT
2025-11-17 23:04:58 +08:00

85 lines
No EOL
2.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import type { APIRoute } from 'astro';
import { createUser } from '@/lib/database';
import { createJWT } from '@/lib/jwt';
export const POST: APIRoute = async ({ request }) => {
try {
const body = await request.text();
if (!body.trim()) {
return new Response(JSON.stringify({ error: '请求体不能为空' }), {
status: 400,
headers: { 'Content-Type': 'application/json' },
});
}
const { username, password } = JSON.parse(body);
// 验证输入
if (!username || !password) {
return new Response(JSON.stringify({ error: '用户名和密码不能为空' }), {
status: 400,
headers: { 'Content-Type': 'application/json' },
});
}
if (username.length < 3) {
return new Response(JSON.stringify({ error: '用户名至少需要3个字符' }), {
status: 400,
headers: { 'Content-Type': 'application/json' },
});
}
if (password.length < 6) {
return new Response(JSON.stringify({ error: '密码至少需要6个字符' }), {
status: 400,
headers: { 'Content-Type': 'application/json' },
});
}
// 创建用户
const user = await createUser({ username, password });
// 创建JWT token
const token = createJWT({
userId: user.id,
username: user.username
});
return new Response(JSON.stringify({
success: true,
user: {
id: user.id,
username: user.username,
created_at: user.created_at
},
token,
expiresIn: 7 * 24 * 60 * 60 // 7天单位
}), {
status: 201,
headers: { 'Content-Type': 'application/json' },
});
} catch (error) {
console.error('注册错误:', error);
let errorMessage = '注册失败,请稍后再试';
if (error instanceof SyntaxError && error.message.includes('JSON')) {
errorMessage = '请求格式错误';
} else if (error instanceof Error && error.message === '用户名已存在') {
errorMessage = '用户名已存在';
return new Response(JSON.stringify({ error: errorMessage }), {
status: 409,
headers: { 'Content-Type': 'application/json' },
});
} else if (error instanceof Error) {
errorMessage = error.message;
}
return new Response(JSON.stringify({ error: errorMessage }), {
status: 500,
headers: { 'Content-Type': 'application/json' },
});
}
};