6-1 auth路由表
src/routes/auth.ts
import Router from '@koa/router'
import { loginController, registerController, userInfoController } from '../controller/auth'
const router = new Router({
prefix: '/api/auth'
})
/**
* 测试接口
**/
router.get('/test', async ctx => {
ctx.body = '只是个测试接口'
})
/**
* 用户注册接口
* /auth/register
*/
router.post('/register', async ctx => {
ctx.body = await registerController(ctx.request.body)
})
/**
* 用户登录
* /auth/login
*/
router.post('/login', async ctx => {
const { username, password } = ctx.request.body
ctx.body = await loginController({ username, password })
})
/**
* /auth/info
* 根据token获取用户信息
*/
router.post('/info', async ctx => {
const token = ctx.header.authorization || ctx.request.body.token
ctx.body = await userInfoController(token)
})
export default router
6-2 auth controller
src/controller/auth.ts
import { createUser, getUserInfo, getUserInfoAndRoles } from '../services/auth'
import { createErrorResponse, ErrorResponse, SuccessResponse } from '../utils/Response'
import errorInfo from '../constants/errorInfo'
import { createMd5 } from '../utils/createMD5'
import { createToken, getInfoByToken } from '../utils/token'
import { allocUserRoleService } from '../services/user'
import { RegisterPropsWithRoles } from './types'
const {
registerUserNameExistInfo,
registerFailInfo,
loginFailInfo,
getUserInfoFailInfo,
accountForbiddenFailInfo
} = errorInfo
/**
* 用户注册controller
* @param params RegisterModel
*/
export const registerController = async (params: RegisterPropsWithRoles) => {
const { username, password = '111111' } = params // 添加用户没设密码默认111111
// 先看下用户是否已注册
const userInfo = await getUserInfo({ username })
if (userInfo) { // 如果已注册
// 用户已注册
const { code, message } = registerUserNameExistInfo
return new ErrorResponse(code, message)
}
const { roleIds = [] } = params
// 用户不存在
try {
const result = await createUser({ // 创建用户
...params,
password: createMd5(password)
})
await allocUserRoleService(result.id, roleIds)
return new SuccessResponse(result)
} catch (err) { // 注册失败
console.log(err.message, err.stack)
const { code, message } = registerFailInfo
return new ErrorResponse(code, message)
}
}
// 登录controller
interface LoginModel {
username: string;
password: string;
}
export const loginController = async (params: LoginModel) => {
const { username, password } = params
// 根据用户名和密码 获取用户信息
const userInfo = await getUserInfo({ username, password })
if (userInfo && !userInfo.status) { // 账号禁用状态 返回异常提示
return createErrorResponse(accountForbiddenFailInfo)
}
if (userInfo) { // 能获取到返回token
const { id, username } = userInfo
const token = createToken({
id,
username
})
return new SuccessResponse({ token })
}
// 获取不到返回 登录失败
const { code, message } = loginFailInfo
return new ErrorResponse(code, message)
}
/**
* 用户信息
* @param param string
*/
interface UserTokenInfo {
id: number;
username: string;
}
export const userInfoController = async (param = '') => {
const token = param.split(' ')[1]
if (token) {
// 根据token解析token信息
const tokenInfo = await getInfoByToken<UserTokenInfo>(token)
if (tokenInfo) {
const { id } = tokenInfo
const userInfo = await getUserInfoAndRoles(id)
return new SuccessResponse(userInfo)
}
}
const { code, message } = getUserInfoFailInfo
return new ErrorResponse(code, message)
}
6-3 auth services
src/services/auth.ts
import UserModel, { RegisterModel, UserModelProps } from '../db/models/user'
import { UserWhereProps } from './types'
import { createMd5 } from '../utils/createMD5'
import { RolesModel, UserRoleModel } from '../db/models'
import { UserInfo } from './types'
/**
* 创建用户
*/
export const createUser = async ({ username, password, email, mobile, status, avatar = '' }: RegisterModel): Promise<UserModelProps> => {
const result = await UserModel.create({
username,
password,
email,
mobile,
status,
avatar
})
return result.toJSON() as UserModelProps
}
/**
* 根据用户名 获取用户信息
* @param username 用户名
* @param password 密码
* @param id 用户id
* @returns 用户信息
*/
export const getUserInfo = async ({ username, password, id }: UserWhereProps): Promise<UserModelProps | null> => {
const where: UserWhereProps = {
username
}
if (password) {
where.password = createMd5(password)
}
if (typeof id != 'undefined') {
where.id = id
}
const result = await UserModel.findOne({
attributes: {
exclude: ['password', 'createdAt', 'updatedAt']
},
where,
})
if (result == null) return null
return result.toJSON() as UserModelProps
}
// 获取用户信息 包含 角色信息
export const getUserInfoAndRoles = async (id: number) => {
const result = await UserModel.findOne({
attributes: ['id', 'username', 'email', 'mobile', 'isSuper', 'status', 'avatar', 'description'],
where: {
id
},
include: [ // 联表查询
{
model: UserRoleModel,
attributes: ['id'],
include: [
{
model: RolesModel,
attributes: ['id', 'name', 'description']
}
]
}
]
})
if (!result) return null
const user = result.toJSON() as UserInfo
user.roles = user.UserRoles?.map(item => item.Role)
delete user.UserRoles
return user
}