change to use session for auth

+ replace BearerAuth to cookieAuth in swagger
+ add swagger.yaml to nodemon watch list
This commit is contained in:
wancat committed 2023-09-17 11:27:37 +08:00
1 parent a6d02f2616
commit be5cd152a9
13 files changed
+216 -71

No files matched your search

+2
View File
@@ -6,6 +6,8 @@ COPY server/package.json ./server/package.json
COPY packages/file-graph/package.json ./packages/file-graph/package.json
RUN yarn install --frozen-lockfile
COPY server/nodemon.json ./server/nodemon.json
ENV NODE_ENV=development
ENV HOST=0.0.0.0
ENV PORT=3000
+4
View File
@@ -0,0 +1,4 @@
{
"watch": ["src", "swagger.yaml"],
"ext": "js,yaml"
}
+2
View File
@@ -13,8 +13,10 @@
"@linux-odyssey/file-graph": "*",
"bcrypt": "^5.1.1",
"commander": "^11.0.0",
"connect-mongo": "^5.0.0",
"dockerode": "^3.3.5",
"express": "^4.18.2",
"express-session": "^1.17.3",
"jsonwebtoken": "^9.0.1",
"minimist": "^1.2.8",
"mongoose": "^7.4.0",
+22 -2
View File
@@ -92,8 +92,15 @@ export async function register(req, res, next) {
user.hashedPassword = await hashPassword(password)
await user.save()
req.user = user
res.status(201)
next()
req.login(user, (err) => {
if (err) {
next(err)
return
}
res.status(201).json({
message: 'user created',
})
})
} catch (err) {
console.error(err)
res.status(500).json({
@@ -101,3 +108,16 @@ export async function register(req, res, next) {
})
}
}
export function logout(req, res) {
req.logout((err) => {
if (err) {
console.error(err)
res.status(500).json({
message: 'error logging out',
})
return
}
res.json({ message: 'success' })
})
}
+8 -4
View File
@@ -2,20 +2,24 @@ import { Router } from 'express'
import passport from 'passport'
import {
issueToken,
register,
checkUsername,
logout,
} from '../controllers/authController.js'
const router = Router()
router.post(
'/login',
passport.authenticate('local', { session: false, failWithError: true }),
issueToken
passport.authenticate('local', { failureMessage: true }),
(req, res) => {
res.json({ message: 'success' })
}
)
router.post('/register', register, issueToken)
router.post('/register', register)
router.post('/logout', logout)
router.get('/check', checkUsername)
+7 -10
View File
@@ -6,6 +6,7 @@ import commands from './commands.js'
import authRouter from './auth.js'
const router = Router()
router.use(passport.authenticate('session'))
router.get('/', (req, res) => {
res.send('Hello API!')
@@ -13,15 +14,11 @@ router.get('/', (req, res) => {
router.use('/auth', authRouter)
router.use('/quests', quests)
router.use(
'/sessions',
passport.authenticate('jwt', { session: false, failWithError: true }),
sessions
)
router.use(
'/commands',
passport.authenticate('jwt', { session: false, failWithError: true }),
commands
)
const authZone = Router()
authZone.use('/sessions', sessions)
authZone.use('/commands', commands)
router.use(authZone)
export default router
-13
View File
@@ -1,13 +0,0 @@
import { Strategy as JwtStrategy, ExtractJwt } from 'passport-jwt'
import config from '../config.js'
const jwtOptions = {
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: config.jwtSecret,
}
function verifyJwt(jwtPayload, done) {
return done(null, jwtPayload)
}
export default new JwtStrategy(jwtOptions, verifyJwt)
+16 -2
View File
@@ -1,6 +1,20 @@
import passport from 'passport'
import PasswordStrategy from './passwordStrategy.js'
import JwtStrategy from './jwtStrategy.js'
passport.use(PasswordStrategy)
passport.use(JwtStrategy)
passport.serializeUser((user, done) => {
process.nextTick(() => {
done(null, {
_id: user._id,
username: user.username,
email: user.email,
})
})
})
passport.deserializeUser((user, done) => {
process.nextTick(() => {
done(null, user)
})
})
+6 -1
View File
@@ -3,10 +3,15 @@ import config from './config.js'
export default async function connectDB() {
try {
await mongoose.connect(config.db)
const db = await mongoose.connect(config.db, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
console.log('Connected to MongoDB')
return db.connection.getClient()
} catch (err) {
console.error(err)
process.exit(1)
return null
}
}
+14 -5
View File
@@ -11,14 +11,12 @@ import apiRouter from './api/routes/index.js'
import loadAndUpdateQuests from './utils/quest.js'
import config from './config.js'
import errorHandler from './middleware/error.js'
import sessionMiddleware from './middleware/session.js'
import expiryRemovalScheduler from './containers/expiryChecker.js'
import { createTestUser } from './utils/auth.js'
async function main() {
const app = express()
const server = http.createServer(app)
socketServer(server)
await connectDB()
const db = await connectDB()
await createTestUser()
@@ -27,8 +25,19 @@ async function main() {
const file = await fs.readFile('./swagger.yaml', 'utf8')
const swaggerDocument = YAML.parse(file)
const app = express()
const server = http.createServer(app)
socketServer(server)
app.use(errorHandler)
app.use('/api-docs', swaggerUI.serve, swaggerUI.setup(swaggerDocument))
app.use(sessionMiddleware(db))
app.use(
'/api-docs',
swaggerUI.serve,
swaggerUI.setup(swaggerDocument, {
withCredentials: true,
})
)
app.use(express.json())
app.get('/', (req, res) => {
+20
View File
@@ -0,0 +1,20 @@
import session from 'express-session'
import MongoStore from 'connect-mongo'
import config from '../config.js'
export default (db) => {
console.log(db.constructor.name)
return session({
secret: config.jwtSecret,
resave: false,
saveUninitialized: false,
cookie: {
httpOnly: true,
},
store: MongoStore.create({
mongoUrl: config.db,
collectionName: 'loginSessions',
}),
})
}
+40 -25
View File
@@ -24,7 +24,7 @@ paths:
- signed-in
summary: list existing sessions of current user
security:
- BearerAuth: []
- cookieAuth: []
parameters:
- in: query
name: quest_id
@@ -52,7 +52,7 @@ paths:
tags:
- signed-in
security:
- BearerAuth: []
- cookieAuth: []
requestBody:
description: session data
content:
@@ -86,7 +86,7 @@ paths:
- signed-in
summary: get a specific session of current user by ID
security:
- BearerAuth: []
- cookieAuth: []
parameters:
- in: path
name: session_id
@@ -117,7 +117,7 @@ paths:
- signed-in
summary: delete a specific session by ID
security:
- BearerAuth: []
- cookieAuth: []
parameters:
- in: path
name: session_id
@@ -176,6 +176,11 @@ paths:
responses:
'201':
description: User created
headers:
Set-Cookie:
schema:
type: string
example: connect.sid=s%3Aq1Z; Path=/; HttpOnly; SameSite=Strict; Secure
content:
application/json:
schema:
@@ -227,15 +232,19 @@ paths:
responses:
'200':
description: User logged in
headers:
Set-Cookie:
schema:
type: string
example: connect.sid=s%3Aq1Z; Path=/; HttpOnly; SameSite=Strict; Secure
content:
application/json:
schema:
type: object
properties:
token:
message:
type: string
description: Access token
example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
example: Logged in successfully
'400':
description: Bad Request
content:
@@ -257,6 +266,25 @@ paths:
type: string
example: Incorrect username or password
/auth/logout:
post:
summary: Log out a user
tags:
- signed-in
security:
- cookieAuth: []
responses:
'200':
description: User logged out
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: Logged out successfully
/auth/check:
get:
summary: Check if the username is already taken
@@ -291,19 +319,6 @@ paths:
type: string
example: Username is already taken
/profile:
get:
summary: Get the profile of current logged-in user
security:
- BearerAuth: []
responses:
'200':
description: Get user's profile
content:
application/json:
schema:
$ref: '#/components/schemas/User'
/quests:
get:
summary: Get quests list
@@ -350,7 +365,7 @@ paths:
tags:
- signed-in
security:
- BearerAuth: []
- cookieAuth: []
requestBody:
required: true
content:
@@ -537,7 +552,7 @@ components:
example: 'Unix Spirit'
securitySchemes:
BearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
cookieAuth:
type: apiKey
in: cookie
name: connect.sid