// src/models/user.ts
// ...
export interface UserInstance extends Model<UserAttributes, UserCreationAttributes>, UserAttributes {
checkPassword: (password: string, callbackfn: CheckPasswordCallback) => void
}
// ...
// src/services/jwtService.ts
import jwt from 'jsonwebtoken'
const secret = 'chave-jwt'
export const jwtService = {
signPayload: (payload: string | object | Buffer, expiration: string) => {
return jwt.sign(payload, secret, { expiresIn: expiration })
},
verifyToken: (token: string, callbackfn: jwt.VerifyCallback) => {
jwt.verify(token, secret, callbackfn)
}
}
// src/middlewares/auth.ts
import { NextFunction, Request, Response } from 'express'
import { JwtPayload } from 'jsonwebtoken'
import { UserInstance } from '../models/user'
import { jwtService } from '../services/jwt-service'
import { userService } from '../services/user-service'
export interface AuthenticatedRequest extends Request {
user?: UserInstance | null
}
export function ensureAuth(req: AuthenticatedRequest, res: Response, next: NextFunction) {
const authorizationHeader = req.headers.authorization
if (!authorizationHeader) {
return res.status(401).json({ message: 'Não autorizado: nenhum token encontrado' })
}
const token = authorizationHeader.replace(/Bearer /, '')
jwtService.verifyToken(token, (err, decoded) => {
if (err || typeof decoded === 'undefined') {
return res.status(401).json({ message: 'Não autorizado: token inválido' })
}
userService.findByEmail((decoded as JwtPayload).email).then(user => {
req.user = user
next()
})
})
}
Por fim, vamos incluir o middleware em todas as rotas que queremos proteger:
Obs.: na rota de lançamentos não iremos utilizar o middleware, pois a utilizaremos em um determinado momento antes de um usuário estar logado, portanto precisamos que ela esteja acessível.
// src/routes.ts
// ...
import { ensureAuth } from './middlewares/auth'
const router = express.Router()
router.post('/auth/register', authController.register)
router.post('/auth/login', authController.login)
router.get('/categories', ensureAuth, categoriesController.index)
router.get('/categories/:id', ensureAuth, categoriesController.show)
router.get('/courses/featured', ensureAuth, coursesController.featured)
router.get('/courses/newest', coursesController.newest)
router.get('/courses/search', ensureAuth, coursesController.search)
router.get('/courses/:id', ensureAuth, coursesController.show)
router.get('/episodes/stream', episodesController.stream)
export { router }