登入系统完成
This commit is contained in:
父節點
5bac90d1a0
當前提交
09ab33cdac
@ -1,4 +1,5 @@
|
|||||||
NDH_PORT=9444
|
NDH_PORT=9444
|
||||||
|
NDH_JWT_SECRET=
|
||||||
|
|
||||||
NDH_DB_HOST=
|
NDH_DB_HOST=
|
||||||
NDH_DB_USER=
|
NDH_DB_USER=
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/cors": "^2.8.12",
|
"@types/cors": "^2.8.12",
|
||||||
"@types/express": "^4.17.13",
|
"@types/express": "^4.17.13",
|
||||||
|
"@types/express-jwt": "^6.0.2",
|
||||||
|
"@types/jsonwebtoken": "^8.5.4",
|
||||||
"@types/node": "^16.4.1",
|
"@types/node": "^16.4.1",
|
||||||
"@types/tough-cookie": "^4.0.1",
|
"@types/tough-cookie": "^4.0.1",
|
||||||
"axios": "^0.21.1",
|
"axios": "^0.21.1",
|
||||||
@ -21,7 +23,9 @@
|
|||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"dotenv": "^10.0.0",
|
"dotenv": "^10.0.0",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
|
"express-jwt": "^6.0.0",
|
||||||
"express-validator": "^6.12.1",
|
"express-validator": "^6.12.1",
|
||||||
|
"jsonwebtoken": "^8.5.1",
|
||||||
"promise-mysql": "^5.0.3",
|
"promise-mysql": "^5.0.3",
|
||||||
"qs": "^6.10.1",
|
"qs": "^6.10.1",
|
||||||
"reflect-metadata": "^0.1.13",
|
"reflect-metadata": "^0.1.13",
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
const appConfig={
|
const appConfig = {
|
||||||
port: process.env.NDH_PORT as any as number,
|
port: process.env.NDH_PORT as any as number,
|
||||||
dbHost: process.env.NDH_DB_HOST,
|
dbHost: process.env.NDH_DB_HOST,
|
||||||
dbUser: process.env.NDH_DB_USER,
|
dbUser: process.env.NDH_DB_USER,
|
||||||
dbPassword: process.env.NDH_DB_PASSWORD,
|
dbPassword: process.env.NDH_DB_PASSWORD,
|
||||||
dbName: process.env.NDH_DB_NAME,
|
dbName: process.env.NDH_DB_NAME,
|
||||||
|
jwtSecret:process.env.NDH_JWT_SECRET || 'default-jwt-secret'
|
||||||
}
|
}
|
||||||
export {appConfig}
|
export {appConfig}
|
||||||
|
@ -21,6 +21,17 @@ let poolCreatingPromise = mysql.createPool({
|
|||||||
console.error('无法连线到资料库')
|
console.error('无法连线到资料库')
|
||||||
process.exit(-1)
|
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() {
|
export function getPoolCreatingPromise() {
|
||||||
return poolCreatingPromise
|
return poolCreatingPromise
|
||||||
@ -62,5 +73,3 @@ export function getAxiosInstance() {
|
|||||||
instance.defaults.jar = new tough.CookieJar()
|
instance.defaults.jar = new tough.CookieJar()
|
||||||
return instance
|
return instance
|
||||||
}
|
}
|
||||||
|
|
||||||
export {db}
|
|
||||||
|
24
src/index.ts
24
src/index.ts
@ -1,20 +1,40 @@
|
|||||||
import 'reflect-metadata'
|
import 'reflect-metadata'
|
||||||
import express from 'express'
|
import express, {NextFunction} from 'express'
|
||||||
import cors from 'cors'
|
import cors from 'cors'
|
||||||
import {appConfig} from "./config"
|
import {appConfig} from "./config"
|
||||||
import {userRouter} from "./routers/user-router"
|
import {userRouter} from "./routers/user-router"
|
||||||
import {getPoolCreatingPromise} from "./includes"
|
import {getPoolCreatingPromise} from "./includes"
|
||||||
|
import expressJWT from 'express-jwt'
|
||||||
|
import type {ErrorRequestHandler} from "express"
|
||||||
|
import {IResultJson} from "./types"
|
||||||
|
|
||||||
const app = express()
|
const app = express()
|
||||||
|
|
||||||
app.use(cors())
|
app.use(cors())
|
||||||
app.use(express.urlencoded({extended: true}))
|
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(<IResultJson>{status: false, data: '使用者未登入'})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
app.use(authErrorHandler)
|
||||||
|
|
||||||
app.use('/user', userRouter)
|
app.use('/user', userRouter)
|
||||||
|
|
||||||
async function entrypoint(){
|
async function entrypoint() {
|
||||||
await getPoolCreatingPromise()
|
await getPoolCreatingPromise()
|
||||||
app.listen(appConfig.port, () => {
|
app.listen(appConfig.port, () => {
|
||||||
console.log('Server started at port ' + appConfig.port)
|
console.log('Server started at port ' + appConfig.port)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
entrypoint()
|
entrypoint()
|
||||||
|
@ -4,11 +4,24 @@ import {IUser} from "../types"
|
|||||||
import {db} from "../includes"
|
import {db} from "../includes"
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class UserModel{
|
export class UserModel {
|
||||||
async insertUser(user:IUser){
|
async insertUser(user: IUser) {
|
||||||
await db.query('insert into users (username,realName,role) values(?,?,?) ' +
|
await db.query('insert into users (username,realName,role) values(?,?,?) ' +
|
||||||
'ON DUPLICATE KEY UPDATE username=username',[
|
'ON DUPLICATE KEY UPDATE username=username', [
|
||||||
user.username,user.realName,user.role
|
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 <IUser>{
|
||||||
|
id: user[0].id,
|
||||||
|
username: user[0].username,
|
||||||
|
realName: user[0].realName,
|
||||||
|
role: user[0].role
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import {Container} from "typedi"
|
|||||||
import {UserService} from "../services/user-service"
|
import {UserService} from "../services/user-service"
|
||||||
import {body, validationResult,} from "express-validator"
|
import {body, validationResult,} from "express-validator"
|
||||||
import {hasValidationErrors} from "../includes"
|
import {hasValidationErrors} from "../includes"
|
||||||
|
import {JWTUserPayload} from "../types"
|
||||||
|
|
||||||
let userService = Container.get(UserService)
|
let userService = Container.get(UserService)
|
||||||
|
|
||||||
@ -11,9 +12,13 @@ let userRouter = express.Router()
|
|||||||
userRouter.post('/login',
|
userRouter.post('/login',
|
||||||
body('username').notEmpty().withMessage('请输入使用者名称'),
|
body('username').notEmpty().withMessage('请输入使用者名称'),
|
||||||
body('password').notEmpty().withMessage('请输入密码'),
|
body('password').notEmpty().withMessage('请输入密码'),
|
||||||
async (req:express.Request, res:express.Response) => {
|
async (req: express.Request, res: express.Response) => {
|
||||||
if(hasValidationErrors(req,res)) return
|
if (hasValidationErrors(req, res)) return
|
||||||
res.json(await userService.login(req.body.username,req.body.password))
|
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}
|
export {userRouter}
|
||||||
|
@ -4,6 +4,9 @@ import {UserModel} from "../models/user-model"
|
|||||||
import {getAxiosInstance, resultJson} from "../includes"
|
import {getAxiosInstance, resultJson} from "../includes"
|
||||||
import {strEnc} from "../helpers/des"
|
import {strEnc} from "../helpers/des"
|
||||||
import qs from 'qs'
|
import qs from 'qs'
|
||||||
|
import jwt from "jsonwebtoken"
|
||||||
|
import {appConfig} from "../config"
|
||||||
|
import {JWTUserPayload} from "../types"
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class UserService {
|
export class UserService {
|
||||||
@ -41,6 +44,16 @@ export class UserService {
|
|||||||
realName,
|
realName,
|
||||||
role: 1
|
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
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,3 +9,9 @@ export interface IUser {
|
|||||||
realName: string,
|
realName: string,
|
||||||
role: 1 | 2
|
role: 1 | 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface JWTUserPayload {
|
||||||
|
id: number,
|
||||||
|
role: 1 | 2
|
||||||
|
}
|
||||||
|
載入中…
x
新增問題並參考
Block a user