登入模块1

This commit is contained in:
juzeon 2021-07-24 21:08:41 +08:00
父節點 61caf5458e
當前提交 fd03c2d08f
共有 8 個檔案被更改,包括 1195 行新增9 行删除

查看文件

@ -14,11 +14,17 @@
"@types/cors": "^2.8.12", "@types/cors": "^2.8.12",
"@types/express": "^4.17.13", "@types/express": "^4.17.13",
"@types/node": "^16.4.1", "@types/node": "^16.4.1",
"@types/tough-cookie": "^4.0.1",
"axios": "^0.21.1",
"axios-cookiejar-support": "^1.0.1",
"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-validator": "^6.12.1",
"promise-mysql": "^5.0.3", "promise-mysql": "^5.0.3",
"qs": "^6.10.1",
"reflect-metadata": "^0.1.13", "reflect-metadata": "^0.1.13",
"tough-cookie": "^4.0.0",
"ts-node": "^10.1.0", "ts-node": "^10.1.0",
"typedi": "^0.10.0" "typedi": "^0.10.0"
} }

1029
src/helpers/des.js Normal file

檔案差異因為檔案過大而無法顯示 載入差異

查看文件

@ -0,0 +1,66 @@
import express, {Request, Response} from "express"
import {validationResult} from "express-validator"
import {IResultJson} from "./types"
import axios from "axios"
import axiosCookieJarSupport from "axios-cookiejar-support"
import tough from 'tough-cookie'
import mysql, {Pool} from 'promise-mysql'
import {appConfig} from "./config"
let db: Pool
let poolCreatingPromise = mysql.createPool({
host: appConfig.dbHost,
user: appConfig.dbName,
password: appConfig.dbPassword,
database: appConfig.dbName
}).then(value => {
db = value
console.log('Pool created.')
}).error(error => {
console.error(error)
console.error('无法连线到资料库')
process.exit(-1)
})
export function getPoolCreatingPromise() {
return poolCreatingPromise
}
export const resultJson = {
success(data: any) {
return <IResultJson>{
status: true,
data: data
}
},
error(data: any) {
return <IResultJson>{
status: false,
data: data
}
}
}
export function hasValidationErrors(req: express.Request, res: express.Response) {
let errors = validationResult(req)
if (!errors.isEmpty()) {
res.json(resultJson.error(errors.array()))
return true
}
return false
}
export function getAxiosInstance() {
let instance = axios.create({
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0'
},
validateStatus: status => true,
withCredentials: true
})
axiosCookieJarSupport(instance)
instance.defaults.jar = new tough.CookieJar()
return instance
}
export {db}

查看文件

@ -3,12 +3,18 @@ import express 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"
const app = express() const app = express()
app.use(cors()) app.use(cors())
app.use(express.urlencoded({extended: true}))
app.use('/user', userRouter)
app.use(userRouter) async function entrypoint(){
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()

查看文件

@ -1,6 +1,14 @@
import 'reflect-metadata'
import {Service} from "typedi" import {Service} from "typedi"
import {IUser} from "../types"
import {db} from "../includes"
@Service() @Service()
class UserModel{ 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
])
}
} }

查看文件

@ -1,5 +1,19 @@
import 'reflect-metadata'
import express from "express" import express from "express"
import {Container} from "typedi"
import {UserService} from "../services/user-service"
import {body, validationResult,} from "express-validator"
import {hasValidationErrors} from "../includes"
let userService = Container.get(UserService)
let userRouter = express.Router() 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))
})
export {userRouter} export {userRouter}

查看文件

@ -0,0 +1,46 @@
import 'reflect-metadata'
import {Inject, Service} from "typedi"
import {UserModel} from "../models/user-model"
import {getAxiosInstance, resultJson} from "../includes"
import {strEnc} from "../helpers/des"
import qs from 'qs'
@Service()
export class UserService {
@Inject()
userModel!: UserModel
async login(username: string, password: string) {
let casUrl = 'https://pass.sdu.edu.cn/cas/login?service=https%3A%2F%2Fservice.sdu.edu.cn%2Ftp_up%2F'
let axios = getAxiosInstance()
let resp = await axios.get(casUrl)
if (resp.status != 200) {
return resultJson.error('无法连线至认证伺服器')
}
let ticket = /name="lt" value="(.*?)"/.exec(resp.data)?.[1] || null
if (!ticket) {
return resultJson.error('无法取得ticket')
}
let rsa = strEnc(username + password + ticket, '1', '2', '3')
resp = await axios.post(casUrl, qs.stringify({
rsa,
ul: username.length.toString(),
pl: password.length.toString(),
execution: 'e1s1',
_eventId: 'submit'
}))
if (resp.status != 200) {
return resultJson.error('无法连线至认证伺服器')
}
if (!resp.data.includes('退出登录')) {
return resultJson.error('使用者名称或密码有误,请重新输入')
}
let realName = / <\/p> <span class="tit">(.*?)</.exec(resp.data)?.[1]!
await this.userModel.insertUser({
username,
realName,
role: 1
})
}
}

11
src/types.ts Normal file
查看文件

@ -0,0 +1,11 @@
export interface IResultJson {
status: boolean,
data: any
}
export interface IUser {
id?: number,
username: string,
realName: string,
role: 1 | 2
}