본문 바로가기

백앤드

Vapor - 로그인 구현하기

이전 글에서 라우팅로직을 간단하게 보고 간단한 JSON Response를 반환하도록 했다. 이번 글에서는 이메일 + 패스워드로 로그인이 가능하도록 하자. 

목표

1. 로그인 전용 API 생성하기

- path: api/user/signIn으로 설정한 후 POST Method로 id(이메일), 패스워드를 전달받도록 함

2. email, password validation

- 입력한 아이디가 이메일 형식에 맞는지, 패스워드가 최소 길이를 충족하는지에 대한 유효성 검사 수행

- CommonError 구성하기(response 에서 throw 하기 위함)

3. 적절한 Response 반환

- 유효성 검사 및 아이디, 패스워드로 로그인 성공 여부에 따라 적절한 응답 내려주기

- 기본 리스폰스(성공/실패)에 대한 틀 만들기

1. 로그인 전용 API 생성하기

기본 리스폰스 구성

일단 get을 썼던것처럼 동일하게 .post로 변경 후 "api", "user", "signIn" 세 개를 전달해 주면 "http://127.0.0.1:8080/api/user/signIn"으로 사용할 수 있을 것 같다. 문제는 입력한 파라미터를 어떻게 받아서 쓸거냐인데..

request의 parameters 프로퍼티 설명

파라미터 프로퍼티 설명을 보면 URL로부터 non-static 한 파라미터를 가져온다고 한다. 예를 들어 "http://127.0.0.1:8080/api/user/signIn?key1=value1&key2=value2"같은 방식이면 아래의 코드처럼 파라미터를 가져다 사용할 수 있을 것 같다.

req.parameters.get

일단 post로 key1, key2를 보낸다고 했을 때는 url에 키벨류가 포함되어서 리퀘스트에 전달되는 형태는 아닐 거고, 아마 x-www-form-urlencoded 방식으로 인코딩 되어서 body에 전달될 것이다.(물론 url에 전달되는 방식("key1=value1&key2=value2")과는 동일한 데이터이다.

 

get으로 요청을 날릴 때는 x-www-form-urlencoded방식을 그대로 사용해도 되겠지만, body에서는 application/json방식으로 인코딩해서 전달하려고 한다.

Request.Body에서 데이터 읽는 방식

Request.Body 구현체를 보니 data를 바이트 버퍼로 받아서 버퍼 길이만큼 읽은 후 String으로 변환할 수 있는 것 같다.

req.body를 그대로 response로 반환하도록 코드 변경

body 문자열을 반환하도록 하고,

postman으로 POST Request 날리기

위와 같이 email, password를 json형식으로 날리게 되면, 예상했던 대로 req.body.string이 그대로 response로 내려오는 것을 확인할 수 있다.

 

2. 이메일, 암호 Validation

기존 앱에서 email validation하던 방식

기존에 앱에서도 위와 같이 정규식을 통해 이메일에 대한 유효성 검사를 수행하고 있었다. 마찬가지로 여기에서도 이 코드를 그대로 적용하면 될 것 같은데, 여기서 한 가지 의문이 드는 점은 routes 부분에서 이러한 코드를 위치시키기에는 부적절해 보였다.

 

이럴 때 쓰라고 Controller를 만들어둔 것 같은데...

 

대애충... 이렇게 하면 되려나..

Error를 따로 만들어서 쓰려고 하다가 귀찮아서 문서를 보니 Abort라는 구조체를 제공하고 있었다. 일반적으로 HTTP Response에서 상태별로 내려주는 코드 및 메시지를 사용할 수 있도록 잘 구현되어 있어서 추가 구현 없이 사용이 가능해 보였다. 클라이언트와 달리(원래 에러 처리를 신경 쓰면서 개발하지는 않았어서) Vapor에서 제공하는 코드들은 기본적으로 에러를 염두에 두고 작성되어 있는 것 같다.

 

적절한 Response 반환

생각해 보니, 클라이언트에서 Request 및 Response 구조체를 각각 정의했던 것 처럼, 당연히 백앤드에서도 Request, Response에 대한 구조체를 정의해줘야했다. 그래서 로그인 리퀘스트에 대한 구조체 및 반환할 User에 대한 구조체를 다음과 같이 정의했다.

user 구조체

이전 Response를 구성했을 때는 다 public 접근제어자를 사용했는데, 생각해보니 같은 패키지에 있는 파일이라서 굳이 필요 없는 거였다. 그래서 새로 구조체를 만들 때는 접근제어자 없이 생성했다.

 

먼저  response에서 data로 반환할 유저 구조체를 먼저 정의해 주고

signInRequest

실제 json으로 받아서 디코딩 후 사용할 로그인 구조체도 정의해 주고

공통으로 사용할 Response 구조체를 정의해서 데이터 및 상태값(성공, 실패)만 전달할 수 있도록 구성했다.

 

마지막으로 아래처럼 깔끔하게 변경된 라우팅 코드로 빌드하게 되면

routes.swift 수정

포스트맨에서 아래와 같은 결과를 확인할 수 있다.

성공 응답

물론 비밀번호를 잘못 입력했을 경우의 실패케이스도 아래처럼 정상 작동하는 것을 확인할 수 있다.

실패 응답


 

이번에는 아이디 패스워드 입력 후 단순히 비교만으로 성공여부를 판단했지만, 회원가입 후 데이터를 DB에 저장하고 가져다 쓰는 방식으로 구현하는 게 일반적이라서, 다음 글에서는 간단하게 DB 스키마를 구성해 보고 회원가입 추가, 로그인 코드 개선 작업을 진행해 봐야겠다.

'백앤드' 카테고리의 다른 글

Vapor - Routing + JSON Response  (1) 2024.01.29
Vapor - 프로젝트 기본 구성  (1) 2024.01.22
Vapor - 시작하기(기본 프로젝트 생성)  (1) 2024.01.22