From 09ab33cdacfb895ff4f17796bdf8c79c9fd9bf0c Mon Sep 17 00:00:00 2001 From: juzeon <812312770@qq.com> Date: Sat, 24 Jul 2021 22:40:01 +0800 Subject: [PATCH] =?UTF-8?q?=E7=99=BB=E5=85=A5=E7=B3=BB=E7=BB=9F=E5=AE=8C?= =?UTF-8?q?=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.example | 1 + package.json | 4 ++++ src/config.ts | 3 ++- src/includes.ts | 13 +++++++++++-- src/index.ts | 24 ++++++++++++++++++++++-- src/models/user-model.ts | 21 +++++++++++++++++---- src/routers/user-router.ts | 13 +++++++++---- src/services/user-service.ts | 13 +++++++++++++ src/types.ts | 6 ++++++ 9 files changed, 85 insertions(+), 13 deletions(-) diff --git a/.env.example b/.env.example index eb87291..b10ba85 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,5 @@ NDH_PORT=9444 +NDH_JWT_SECRET= NDH_DB_HOST= NDH_DB_USER= diff --git a/package.json b/package.json index 5bf53c3..538f43f 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,8 @@ "dependencies": { "@types/cors": "^2.8.12", "@types/express": "^4.17.13", + "@types/express-jwt": "^6.0.2", + "@types/jsonwebtoken": "^8.5.4", "@types/node": "^16.4.1", "@types/tough-cookie": "^4.0.1", "axios": "^0.21.1", @@ -21,7 +23,9 @@ "cors": "^2.8.5", "dotenv": "^10.0.0", "express": "^4.17.1", + "express-jwt": "^6.0.0", "express-validator": "^6.12.1", + "jsonwebtoken": "^8.5.1", "promise-mysql": "^5.0.3", "qs": "^6.10.1", "reflect-metadata": "^0.1.13", diff --git a/src/config.ts b/src/config.ts index ddddc0c..ad203e0 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,9 +1,10 @@ require('dotenv').config() -const appConfig={ +const appConfig = { port: process.env.NDH_PORT as any as number, dbHost: process.env.NDH_DB_HOST, dbUser: process.env.NDH_DB_USER, dbPassword: process.env.NDH_DB_PASSWORD, dbName: process.env.NDH_DB_NAME, + jwtSecret:process.env.NDH_JWT_SECRET || 'default-jwt-secret' } export {appConfig} diff --git a/src/includes.ts b/src/includes.ts index 531d344..13a9a7f 100644 --- a/src/includes.ts +++ b/src/includes.ts @@ -21,6 +21,17 @@ let poolCreatingPromise = mysql.createPool({ console.error('无法连线到资料库') process.exit(-1) }) +export {db} + +// let redisClient = redis.createClient({ +// host: appConfig.redisHost, +// port: appConfig.redisPort +// }) +// redisClient.on('error', errors => { +// console.error(errors) +// }) +// export let redisGet = promisify(redisClient.get).bind(redisClient) +// export let redisSet = promisify(redisClient.set).bind(redisClient) export function getPoolCreatingPromise() { return poolCreatingPromise @@ -62,5 +73,3 @@ export function getAxiosInstance() { instance.defaults.jar = new tough.CookieJar() return instance } - -export {db} diff --git a/src/index.ts b/src/index.ts index b152a2e..b79a527 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,20 +1,40 @@ import 'reflect-metadata' -import express from 'express' +import express, {NextFunction} from 'express' import cors from 'cors' import {appConfig} from "./config" import {userRouter} from "./routers/user-router" import {getPoolCreatingPromise} from "./includes" +import expressJWT from 'express-jwt' +import type {ErrorRequestHandler} from "express" +import {IResultJson} from "./types" const app = express() app.use(cors()) app.use(express.urlencoded({extended: true})) +app.use( + expressJWT({ + algorithms: ['HS256'], secret: appConfig.jwtSecret + }).unless({path: ['/user/login']}) +) +const authErrorHandler: ErrorRequestHandler = + (err, + req + , res + , next) => { + if (err.name == 'UnauthorizedError') { + res.status(401).send({status: false, data: '使用者未登入'}) + } + } +app.use(authErrorHandler) + app.use('/user', userRouter) -async function entrypoint(){ +async function entrypoint() { await getPoolCreatingPromise() app.listen(appConfig.port, () => { console.log('Server started at port ' + appConfig.port) }) } + entrypoint() diff --git a/src/models/user-model.ts b/src/models/user-model.ts index 4dbd9e1..8aaf6e5 100644 --- a/src/models/user-model.ts +++ b/src/models/user-model.ts @@ -4,11 +4,24 @@ import {IUser} from "../types" import {db} from "../includes" @Service() -export class UserModel{ - async insertUser(user:IUser){ +export class UserModel { + async insertUser(user: IUser) { await db.query('insert into users (username,realName,role) values(?,?,?) ' + - 'ON DUPLICATE KEY UPDATE username=username',[ - user.username,user.realName,user.role + 'ON DUPLICATE KEY UPDATE username=username', [ + user.username, user.realName, user.role ]) } + + async findUserByUsername(username: string) { + let user = await db.query('select * from users where username=?', [username]) + if (!user.length) { + return null + } + return { + id: user[0].id, + username: user[0].username, + realName: user[0].realName, + role: user[0].role + } + } } diff --git a/src/routers/user-router.ts b/src/routers/user-router.ts index 80bab25..3e1b5c1 100644 --- a/src/routers/user-router.ts +++ b/src/routers/user-router.ts @@ -4,6 +4,7 @@ import {Container} from "typedi" import {UserService} from "../services/user-service" import {body, validationResult,} from "express-validator" import {hasValidationErrors} from "../includes" +import {JWTUserPayload} from "../types" let userService = Container.get(UserService) @@ -11,9 +12,13 @@ let userRouter = express.Router() userRouter.post('/login', body('username').notEmpty().withMessage('请输入使用者名称'), body('password').notEmpty().withMessage('请输入密码'), - async (req:express.Request, res:express.Response) => { - if(hasValidationErrors(req,res)) return - res.json(await userService.login(req.body.username,req.body.password)) - }) + async (req: express.Request, res: express.Response) => { + if (hasValidationErrors(req, res)) return + res.json(await userService.login(req.body.username, req.body.password)) + } +) +userRouter.get('/me',async (req:express.Request,res:express.Response)=>{ + res.json(await userService.me(req.user as JWTUserPayload)) +}) export {userRouter} diff --git a/src/services/user-service.ts b/src/services/user-service.ts index 02864e5..97d5b11 100644 --- a/src/services/user-service.ts +++ b/src/services/user-service.ts @@ -4,6 +4,9 @@ import {UserModel} from "../models/user-model" import {getAxiosInstance, resultJson} from "../includes" import {strEnc} from "../helpers/des" import qs from 'qs' +import jwt from "jsonwebtoken" +import {appConfig} from "../config" +import {JWTUserPayload} from "../types" @Service() export class UserService { @@ -41,6 +44,16 @@ export class UserService { realName, role: 1 }) + let user = await this.userModel.findUserByUsername(username) + let token = 'Bearer ' + + jwt.sign({id: user?.id, role: user?.role}, appConfig.jwtSecret, {algorithm: 'HS256'}) + return resultJson.success(token) + } + async me(user: JWTUserPayload) { + return resultJson.success({ + id: user.id, + role: user.role + }) } } diff --git a/src/types.ts b/src/types.ts index 4643d98..d56b184 100644 --- a/src/types.ts +++ b/src/types.ts @@ -9,3 +9,9 @@ export interface IUser { realName: string, role: 1 | 2 } + + +export interface JWTUserPayload { + id: number, + role: 1 | 2 +}