-
[Nest.js] 10 - Authentification - sign up, log inNest.js 2021. 9. 13. 19:11
Contents
1. Unique username
2. Error handling
3. Encryption password
4. Log in
1. Unique "username"
- src/auth/user.entity.ts
... @Entity() @Unique(['username']) // 1 export class User extends BaseEntity { ... }
// 1. set up "username" column has a unique constaint in its table.
2. Error Handling
- user table
- request and response
// when trying to insert a user with the same username, "JinseoCha",
it responded "500 Internal Server Error", which is not enough information which is occurred in the server.- src/auth/user.repository.ts : add try ~ catch
... @EntityRepository(User) export class UserRepository extends Repository<User> { async createUser(AuthCredentialsDto: AuthCredentialsDto): Promise<void> { const { username, password } = AuthCredentialsDto; const user = this.create({ username, password }); try { await this.save(user); } catch (error) { console.log(error) // 1 if (error.code === 'ER_DUP_ENTRY') { // 2 throw new ConflictException('Existing username'); // 3 } else { throw new InternalServerErrorException(); // 4 } } } }
// 1. error in console.log
QueryFailedError: ER_DUP_ENTRY: Duplicate entry 'JinseoCha' for key 'user.IDX_78a916df40e02a9deb1c4b75ed' ... code: 'ER_DUP_ENTRY', // HERE IS THE CODE ! errno: 1062, sqlMessage: "Duplicate entry 'JinseoCha' for key 'user.IDX_78a916df40e02a9deb1c4b75ed'", sqlState: '23000', index: 0, sql: "INSERT INTO `user`(`id`, `username`, `password`) VALUES (DEFAULT, 'JinseoCha', 'passJinseo')" }
// 2. error.code === 'ER_DUP_ENTRY' : use the error's property code to throw the exception property.
// 3. ER_DUP_ENTRY : 409 Status code
// 4. nternalServerErrorExeption() : handle other issue to 500 Status code
- Handled Response
3. Encryption password
- Bcrypt : plain password -> salt + plain password -> Hashed password
e.g. : 1234 -> d1hjskahdj_1234 -> dsadhwjkalshdjqbhjsabdwahkasjd(something like this)- CLI : bcryptjs module
$ npm install bcryptjs --save
- src/auth/user.repository.ts
... import * as bcrypt from 'bcryptjs'; // 1 @EntityRepository(User) export class UserRepository extends Repository<User> { async createUser(AuthCredentialsDto: AuthCredentialsDto): Promise<void> { const { username, password } = AuthCredentialsDto; // bcrypt password const salt = await bcrypt.genSalt(); // 2 const hashedPassword = await bcrypt.hash(password, salt); // 3 const user = this.create({ username, password: hashedPassword }); try { await this.save(user); } catch (error) { console.log(error); if (error.code === 'ER_DUP_ENTRY') { throw new ConflictException('Existing username'); } else { throw new InternalServerErrorException(); } } } }
// 1. import bcryptjs module into the repository
// 2. await bcrypt.genSalt() : need a unique salt first.
// 3. await bcrypt.hash(password, salt) : make an hashed(encrypted) password
- Request 1
- Result 1 in user table
- Request 2 with the same password
- Result 2 in user table
# Even though the users input passwords are the same, they saved a unique/hashed value in database.
4. Log in
- src/auth/auth.controller.ts
import { Body, Controller, Post } from '@nestjs/common'; import { AuthService } from './auth.service'; import { AuthCredentialsDto } from './dto/auth-credential.dto'; @Controller('auth') export class AuthController { constructor(private authService: AuthService) {} @Post('/signup') signUp(@Body() authCredentialsDto: AuthCredentialsDto): Promise<void> { return this.authService.signUp(authCredentialsDto); } @Post('/login') signIn(@Body() authCredentialsDto: AuthCredentialsDto): Promise<string> { return this.authService.signIn(authCredentialsDto); } }
- src/auth/user.service.ts
... import * as bcrypt from 'bcryptjs'; // 1 @Injectable() export class AuthService { constructor( @InjectRepository(UserRepository) private userRepository: UserRepository, ) {} async signUp(authCredentialsDto: AuthCredentialsDto): Promise<void> { return this.userRepository.createUser(authCredentialsDto); } async signIn(authCredentialsDto: AuthCredentialsDto): Promise<string> { const { username, password } = authCredentialsDto; const user = await this.userRepository.findOne({ username }); if (user && (await bcrypt.compare(password, user.password))) { // 2 return 'login success'; } else { throw new UnauthorizedException('login failed'); // 3 } } }
// 1. import bcryptjs module into AuthService
// 2. await bcrypt.compare(password, user.password) : check the input password with encrypted password
// 3. Exception handling : 401 ERROR STATUS
- Log in success
- Log in failed
'Nest.js' 카테고리의 다른 글
[Nest.js] 12 - Authentification - Passport & JWT (0) 2021.09.15 [Nest.js] 11 - Authentification - JWT (0) 2021.09.14 [Nest.js] 9 - Authentification - module/components (0) 2021.09.13 [Nest.js] 8 - CRUD summary code(#1 ~ #7) (0) 2021.09.10 [Nest.js] 7- Entity & Repository (0) 2021.09.09