Files
services/middleware/auth.js
T

73 lines
1.9 KiB
JavaScript
Raw Normal View History

2026-06-03 14:15:55 +08:00
const { query } = require('../config/database')
const { verifyToken } = require('../utils/jwt')
const { decodeBasicAuth } = require('../utils/legacy-token')
const ROLE_USER = 0
const ROLE_STAFF = 1
const ROLE_ADMIN = 2
async function getUserByToken(token) {
if (!token) return null
if (token.startsWith('legacy.')) {
return decodeBasicAuth(token.slice(7))
}
const payload = verifyToken(token)
if (!payload) return null
const users = await query(
'SELECT id, phone, name, avatar, points, role, status, openid FROM users WHERE id = ? AND status = 1',
[payload.sub]
)
return users[0] || null
}
function extractToken(ctx) {
const header = ctx.headers.authorization || ''
if (header.startsWith('Bearer ')) return header.slice(7).trim()
return ctx.query.token || ''
}
function deny(ctx, status, message) {
ctx.status = status
ctx.body = { code: status, message }
return null
}
function requireAuth() {
return async (ctx, next) => {
const token = extractToken(ctx)
if (!token) return deny(ctx, 401, '未登录,请先登录')
const user = await getUserByToken(token)
if (!user) return deny(ctx, 401, '登录已失效,请重新登录')
ctx.state.user = user
return next()
}
}
function requireRole(...roles) {
const allow = new Set(roles)
return async (ctx, next) => {
const token = extractToken(ctx)
if (!token) return deny(ctx, 401, '未登录,请先登录')
const user = await getUserByToken(token)
if (!user) return deny(ctx, 401, '登录已失效,请重新登录')
if (!allow.has(user.role)) return deny(ctx, 403, '权限不足')
ctx.state.user = user
return next()
}
}
const requireStaffAuth = () => requireRole(ROLE_STAFF, ROLE_ADMIN)
const requireAdminAuth = () => requireRole(ROLE_ADMIN)
module.exports = {
ROLE_USER,
ROLE_STAFF,
ROLE_ADMIN,
extractToken,
getUserByToken,
requireAuth,
requireRole,
requireStaffAuth,
requireAdminAuth
}