Description
Middleware:
import jwt from 'jsonwebtoken';
import { ExpressMiddlewareInterface, Middleware } from 'routing-controllers';
import { Logger, LoggerInterface } from '../../decorators/Logger';
@Middleware({ type: 'before' })
export class JwtAuthMiddleware implements ExpressMiddlewareInterface {
constructor(
@Logger(__filename) private log: LoggerInterface
) { }
public use(req: any, res: any, next: (err?: any) => any): void {
const headers = req.headers as { authorization?: string } || req.headers['0'];
const authHeader = headers.authorization;
const authorization = req.header('authorization');
console.log('authorization', authorization);
// console.log('Headers:', req.headers);
this.log.info('show token', headers);
// console.log('res', res);
if (!authHeader) {
return res.status(401).send({ message: 'No token provided' });
}
const token = authHeader.split(' ')[1];
if (!token) {
return res.status(401).send({ message: 'Invalid token' });
}
jwt.verify(token, 'your-secret-key', (err, user) => {
if (err) {
return res.status(403).send({ message: 'Token is not valid' });
}
req.user = user;
next();
});
}
}
Controller:
import { IsNotEmpty } from 'class-validator';
import { Body, JsonController, Post, Req, Res } from 'routing-controllers';
import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi';
import { Logger, LoggerInterface } from '../../decorators/Logger';
import { AuthService } from '../services/AuthService';
// import { UserService } from '../services/UserService';
import { UserResponse } from './UserController';
class LoginBody {
@isnotempty()
public username: string;
@IsNotEmpty()
public password: string;
}
@jsoncontroller('/auth')
@openapi({ security: [{ basicAuth: [] }] })
export class AuthController {
constructor(
// private userService: UserService,
private authService: AuthService,
@Logger(__filename) private log: LoggerInterface
) { }
@Post('/login')
@ResponseSchema(UserResponse)
public async login(@Body() body: LoginBody, @Res() res: any): Promise<any> {
this.log.info(`Received login request with body: ${JSON.stringify(body)}`);
const { user, token } = await this.authService.validateUser(body.username, body.password);
if (!user) {
return res.status(401).send({ message: 'Invalid username or password' });
}
res.status(200).send({
status: 200,
message: 'Login success',
access_token: token,
token_type: 'Bearer',
user: {
username: user.username,
},
});
}
@Post('/logout')
public async logout(@Req() req: any, @Res() res: any): Promise<void> {
const token = req.headers.authorization.split(' ')[1];
await this.authService.invalidateToken(token);
res.status(200).send({ message: 'Logged out successfully' });
}
}
Service
import bcrypt from 'bcrypt';
import jwt from 'jsonwebtoken';
import { Service } from 'typedi';
import { Logger, LoggerInterface } from '../../decorators/Logger';
import { User } from '../models/User';
import { UserService } from './UserService';
@service()
export class AuthService {
constructor(
private userService: UserService,
@Logger(__filename) private log: LoggerInterface
) { }
public async validateUser(username: string, password: string): Promise<{ user: User | null, token?: string }> {
this.log.info(`Validating user: ${username}, ${password}`);
const user = await this.userService.findByUsername(username);
if (user && await bcrypt.compare(password, user.password)) {
const token = this.createToken(user);
return { user, token };
}
return { user: undefined };
}
public createToken(user: User): string {
return jwt.sign({ id: user.id, username: user.username }, 'your-secret-key', { expiresIn: '1h' });
}
public async invalidateToken(token: string): Promise<void> {
// Implement token invalidation logic here (e.g., adding the token to a blacklist)
}
}
Repository
import knex, { Knex } from 'knex';
import { EntityRepository, Repository } from 'typeorm';
import knexConfig from '../../../src/knexfile';
import { User } from '../models/User';
const environment = process.env.NODE_ENV || 'development';
const DB: Knex = knex(knexConfig[environment]);
@entityrepository(User)
export class UserRepository extends Repository {
public async findOneByUsername(username: string): Promise<User | undefined> {
const user = await DB('user')
.where({ username })
.first();
return user;
}
}
But I always failed