Skip to content

How to create login and logout feature?  #269

Open
@saadabdurrazaq

Description

@saadabdurrazaq

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions