init
This commit is contained in:
101
backend/src/middlewares/auth.ts
Normal file
101
backend/src/middlewares/auth.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
import { Context, Next } from 'hono';
|
||||
import jwt from 'jsonwebtoken';
|
||||
import config from '../config';
|
||||
import supabase from '../utils/supabase';
|
||||
|
||||
// Interface for JWT payload
|
||||
interface JwtPayload {
|
||||
sub: string;
|
||||
email: string;
|
||||
iat: number;
|
||||
exp: number;
|
||||
}
|
||||
|
||||
// Middleware to verify JWT token
|
||||
export const authMiddleware = async (c: Context, next: Next) => {
|
||||
try {
|
||||
// Get authorization header
|
||||
const authHeader = c.req.header('Authorization');
|
||||
|
||||
if (!authHeader || !authHeader.startsWith('Bearer ')) {
|
||||
return c.json({ error: 'Unauthorized: No token provided' }, 401);
|
||||
}
|
||||
|
||||
// Extract token
|
||||
const token = authHeader.split(' ')[1];
|
||||
|
||||
try {
|
||||
// 验证 JWT token
|
||||
const decoded = jwt.verify(token, config.jwt.secret) as JwtPayload;
|
||||
|
||||
// 特殊处理 Swagger 测试 token
|
||||
if (decoded.sub === 'swagger-test-user' && decoded.email === 'swagger@test.com') {
|
||||
// 为 Swagger 测试设置一个模拟用户
|
||||
c.set('user', {
|
||||
id: 'swagger-test-user',
|
||||
email: 'swagger@test.com',
|
||||
name: 'Swagger Test User'
|
||||
});
|
||||
|
||||
// 继续到下一个中间件或路由处理器
|
||||
await next();
|
||||
return;
|
||||
}
|
||||
|
||||
// 设置用户信息到上下文
|
||||
c.set('user', {
|
||||
id: decoded.sub,
|
||||
email: decoded.email
|
||||
});
|
||||
|
||||
// 继续到下一个中间件或路由处理器
|
||||
await next();
|
||||
} catch (jwtError) {
|
||||
if (jwtError instanceof jwt.JsonWebTokenError) {
|
||||
return c.json({ error: 'Unauthorized: Invalid token' }, 401);
|
||||
}
|
||||
|
||||
if (jwtError instanceof jwt.TokenExpiredError) {
|
||||
return c.json({ error: 'Unauthorized: Token expired' }, 401);
|
||||
}
|
||||
|
||||
throw jwtError;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Auth middleware error:', error);
|
||||
return c.json({ error: 'Internal server error' }, 500);
|
||||
}
|
||||
};
|
||||
|
||||
// Generate JWT token
|
||||
export const generateToken = (userId: string, email: string): string => {
|
||||
const secret = config.jwt.secret;
|
||||
const expiresIn = config.jwt.expiresIn;
|
||||
|
||||
return jwt.sign(
|
||||
{
|
||||
sub: userId,
|
||||
email,
|
||||
},
|
||||
secret,
|
||||
{
|
||||
expiresIn,
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
// Verify Supabase token
|
||||
export const verifySupabaseToken = async (token: string) => {
|
||||
try {
|
||||
const { data, error } = await supabase.auth.getUser(token);
|
||||
|
||||
if (error || !data.user) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return data.user;
|
||||
} catch (error) {
|
||||
console.error('Supabase token verification error:', error);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user