image.png

6-1 auth路由表

src/routes/auth.ts

  1. import Router from '@koa/router'
  2. import { loginController, registerController, userInfoController } from '../controller/auth'
  3. const router = new Router({
  4. prefix: '/api/auth'
  5. })
  6. /**
  7. * 测试接口
  8. **/
  9. router.get('/test', async ctx => {
  10. ctx.body = '只是个测试接口'
  11. })
  12. /**
  13. * 用户注册接口
  14. * /auth/register
  15. */
  16. router.post('/register', async ctx => {
  17. ctx.body = await registerController(ctx.request.body)
  18. })
  19. /**
  20. * 用户登录
  21. * /auth/login
  22. */
  23. router.post('/login', async ctx => {
  24. const { username, password } = ctx.request.body
  25. ctx.body = await loginController({ username, password })
  26. })
  27. /**
  28. * /auth/info
  29. * 根据token获取用户信息
  30. */
  31. router.post('/info', async ctx => {
  32. const token = ctx.header.authorization || ctx.request.body.token
  33. ctx.body = await userInfoController(token)
  34. })
  35. export default router

6-2 auth controller

src/controller/auth.ts

  1. import { createUser, getUserInfo, getUserInfoAndRoles } from '../services/auth'
  2. import { createErrorResponse, ErrorResponse, SuccessResponse } from '../utils/Response'
  3. import errorInfo from '../constants/errorInfo'
  4. import { createMd5 } from '../utils/createMD5'
  5. import { createToken, getInfoByToken } from '../utils/token'
  6. import { allocUserRoleService } from '../services/user'
  7. import { RegisterPropsWithRoles } from './types'
  8. const {
  9. registerUserNameExistInfo,
  10. registerFailInfo,
  11. loginFailInfo,
  12. getUserInfoFailInfo,
  13. accountForbiddenFailInfo
  14. } = errorInfo
  15. /**
  16. * 用户注册controller
  17. * @param params RegisterModel
  18. */
  19. export const registerController = async (params: RegisterPropsWithRoles) => {
  20. const { username, password = '111111' } = params // 添加用户没设密码默认111111
  21. // 先看下用户是否已注册
  22. const userInfo = await getUserInfo({ username })
  23. if (userInfo) { // 如果已注册
  24. // 用户已注册
  25. const { code, message } = registerUserNameExistInfo
  26. return new ErrorResponse(code, message)
  27. }
  28. const { roleIds = [] } = params
  29. // 用户不存在
  30. try {
  31. const result = await createUser({ // 创建用户
  32. ...params,
  33. password: createMd5(password)
  34. })
  35. await allocUserRoleService(result.id, roleIds)
  36. return new SuccessResponse(result)
  37. } catch (err) { // 注册失败
  38. console.log(err.message, err.stack)
  39. const { code, message } = registerFailInfo
  40. return new ErrorResponse(code, message)
  41. }
  42. }
  43. // 登录controller
  44. interface LoginModel {
  45. username: string;
  46. password: string;
  47. }
  48. export const loginController = async (params: LoginModel) => {
  49. const { username, password } = params
  50. // 根据用户名和密码 获取用户信息
  51. const userInfo = await getUserInfo({ username, password })
  52. if (userInfo && !userInfo.status) { // 账号禁用状态 返回异常提示
  53. return createErrorResponse(accountForbiddenFailInfo)
  54. }
  55. if (userInfo) { // 能获取到返回token
  56. const { id, username } = userInfo
  57. const token = createToken({
  58. id,
  59. username
  60. })
  61. return new SuccessResponse({ token })
  62. }
  63. // 获取不到返回 登录失败
  64. const { code, message } = loginFailInfo
  65. return new ErrorResponse(code, message)
  66. }
  67. /**
  68. * 用户信息
  69. * @param param string
  70. */
  71. interface UserTokenInfo {
  72. id: number;
  73. username: string;
  74. }
  75. export const userInfoController = async (param = '') => {
  76. const token = param.split(' ')[1]
  77. if (token) {
  78. // 根据token解析token信息
  79. const tokenInfo = await getInfoByToken<UserTokenInfo>(token)
  80. if (tokenInfo) {
  81. const { id } = tokenInfo
  82. const userInfo = await getUserInfoAndRoles(id)
  83. return new SuccessResponse(userInfo)
  84. }
  85. }
  86. const { code, message } = getUserInfoFailInfo
  87. return new ErrorResponse(code, message)
  88. }

6-3 auth services

src/services/auth.ts

  1. import UserModel, { RegisterModel, UserModelProps } from '../db/models/user'
  2. import { UserWhereProps } from './types'
  3. import { createMd5 } from '../utils/createMD5'
  4. import { RolesModel, UserRoleModel } from '../db/models'
  5. import { UserInfo } from './types'
  6. /**
  7. * 创建用户
  8. */
  9. export const createUser = async ({ username, password, email, mobile, status, avatar = '' }: RegisterModel): Promise<UserModelProps> => {
  10. const result = await UserModel.create({
  11. username,
  12. password,
  13. email,
  14. mobile,
  15. status,
  16. avatar
  17. })
  18. return result.toJSON() as UserModelProps
  19. }
  20. /**
  21. * 根据用户名 获取用户信息
  22. * @param username 用户名
  23. * @param password 密码
  24. * @param id 用户id
  25. * @returns 用户信息
  26. */
  27. export const getUserInfo = async ({ username, password, id }: UserWhereProps): Promise<UserModelProps | null> => {
  28. const where: UserWhereProps = {
  29. username
  30. }
  31. if (password) {
  32. where.password = createMd5(password)
  33. }
  34. if (typeof id != 'undefined') {
  35. where.id = id
  36. }
  37. const result = await UserModel.findOne({
  38. attributes: {
  39. exclude: ['password', 'createdAt', 'updatedAt']
  40. },
  41. where,
  42. })
  43. if (result == null) return null
  44. return result.toJSON() as UserModelProps
  45. }
  46. // 获取用户信息 包含 角色信息
  47. export const getUserInfoAndRoles = async (id: number) => {
  48. const result = await UserModel.findOne({
  49. attributes: ['id', 'username', 'email', 'mobile', 'isSuper', 'status', 'avatar', 'description'],
  50. where: {
  51. id
  52. },
  53. include: [ // 联表查询
  54. {
  55. model: UserRoleModel,
  56. attributes: ['id'],
  57. include: [
  58. {
  59. model: RolesModel,
  60. attributes: ['id', 'name', 'description']
  61. }
  62. ]
  63. }
  64. ]
  65. })
  66. if (!result) return null
  67. const user = result.toJSON() as UserInfo
  68. user.roles = user.UserRoles?.map(item => item.Role)
  69. delete user.UserRoles
  70. return user
  71. }

目前最新源码

https://gitee.com/brolly/vue3-admin-server