westagram이라는 django project, 그리고 user라는 django app을 만든 상태다.
휴대폰 번호 및 이메일은 다른 사용자와 중복이 안되어야(unique) 하며 유저네임 또한 중복되면 안된다. 비밀번호는 8자 이상만 가능하다.
unique=True
를 줘서 고유값으로 설정한다.null=True
를 적용해 하나는 null값이 들어갈 수 있게 설정한다. created_at
는 auto_now_add=True
를 적용해 생성시 바로 DateTime이 붙는 방식으로, modified_at
는 auto_now
를 줘서 수정하는 시간의 DateTime이 붙도록 만들었다. mysql로 가서 데이터베이스를 하나 생성한다. 그리고 해당 데이터베이스 이름 및 비밀번호를 settings.py에 입력한다.
manage.py가 있는 디렉토리로 가서
python manage.py makemigrations user
및python manage.py migrate user
를 해서 데이터베이스에 칼럼을 만든다.
include
함수를 이용해서 리펙토링한다. 그리고 include
함수 안에 user.urls
를 써서 user앱 url을 관리한다.
user 앱 안에 urls.py를 생성해 as_view()
를 활용해 해당되는 view를 가져온다. 회원가입을 signup
그리고 로그인을 signin
으로 url을 설정했다.
일단 json, re(파이썬 정규 표현식을 지원하기 위한 친구), brcypt와 jwt(로그인시 토큰 발행을 위한 친구)등 파이썬 모듈을 import한다. 그리고 기타 JsonResponse, HttpResponse, View, Q 등 필요한 장고 모듈을 import한다.
내가 만든 user 앱의 models를 가져온다.
westagram project에서 my_settings안에 있는 SECRET_KEY, ALGORITHM을 가져온다. 추후 로그인 기능 구현시 필요하다..
email_regex
, password_regex
, phone_regex
라는 정규 표현식 validation 조건을 만든다.
추후 적용하기 위해 최소 비밀번호 길이(MINIMUM_PASSWORD_LENGTH) 변수를 선언한다.
json.loads
를 써서 파이썬이 읽을 수 있는 딕셔너리 데이터 타입으로 변환한다.email, password, phone이 앞서 선언한 validation 조건과 맞는지 확인한다.
{"message" : "SUCCESS"}
를 return 한다.인스타그램 로그인을 확인해보면 입력창은 총 2개다. 유저는:
1. 휴대폰 번호, 유저네임, 이메일 중 1개 입력
2. 그리고 비밀번호를 입력해야지 로그인할 수 있다
우리는 사용자가 휴대폰 번호, 유저네임, 이메일 중 어떤 값을 입력할지 모른다. 3개 중 1개의 값만 받으면 되기 때문이다. 즉 이들 중 1개를 받았을 때, 그것이:
1. (사용자가 입력한) 휴대폰 번호, 유저네임, 이메일 DB에 존재하는지
2. (사용자가 입력한) 비밀번호는 우리가 암호화시킨 비밀번호와 일치하는지
3. (사용자) 정보 일치 확인 후 access token 발행해야 한다.
SignUp과 똑같이 urlspatterns
안에 /singin
과 SingInView를 연결한다.
SignUp과 똑같은 models.py에 User
class를 쓴다.
위에 선언한 class SignUpView 밑에 위치한 코드다.
1.. json.loads
를 써서 파이썬이 읽을 수 있는 딕셔너리 데이터 타입으로 변환한다.
2. 프론트에서 받은 json 바디 속 데이터들을 하나씩 변수 안에 넣는다.
3. 사용자가 email, phone, username, password를 입력했는지 확인한다. 파이썬의 .get()
을 활용해 사용자가 어느 값을 입력 안할 시 None을 받을 수 있게 data.get('something_in_request_body', None)
와 같이 입력한다.
4. 만약 email, username, phone 중 한 값 + 비밀번호를 같이 넘기지 않을 시 REQUIRED_FIELD가 뜨게끔 JsonMessage를 설정한다.
5. DB 안에 사용자가 입력한 email, username, phone 중 한 값이 존재하는지, 그리고 존재한다면 그 값을 .get()
한다.
filter는 여러값을 get는 하나의 값만 가져올 수 있다.
.checkpw
함수로 확인한다. access_token
을 발행한다.binaryfield로 설정안해서 나타나는 문제라고 생각하고 charfield로 바꾸고 다시 migration을 진행했다. 그러나 다른 Error가 떴다... 사태가 더 심각해지기 전에 charField로 다시 바꾸고 구글링을 해봤다. stackoverflow에서 hashed_password를 데이터베이스에 load하기 전에 decode를 해야 한다고 써져있었다. 그렇게 코드를 수정하니 성공적으로 hashed_password를 받을 수 있었다.
hashed_password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
hashed_password가 성공적으로 나왔다!
🖤encode(), decode()의 차이🖤
encode(): byte 타입으로 변환. decode()는 string 타입으로 변환한다.
'@'를 뺀 이메일 패턴을 입력할 시 email_regex.search(email)
으로 내가 선언한 email = data['email']
과 email validation 변수 email_regex
가 search 되는지 확인한다.
🖤search vs match의 차이🖤
https://docs.python.org/3/library/re.html#search-vs-match
http 요청을 보낼시 자주 뜨는 에러다. 보통 복붙해서 생기는 quotation mark 문제다.
Queryset로 리턴된 user
를 user.id
로 뽑으려고 했을 때 나타난 에러다. get으로 id를 구하던지 아니면 특정 index로 뽑아야 한다.
json 형태 즉 딕셔너리로 값을 안 넘겼을 때 나는 에러다.
여러 값을 입력해야하는 객체에게 하나의 값을 넣어 계속 create할 때 발생하는 에러다.
User.objects.create(name=name)
User.objects.create(email=email)
User.objects.create(phone=phone)
User.objects.create(password=hashed_password)
User.objects.create(username=username)
User.objects.create(
name = name,
email = email,
phone = phone,
password = hashed_password,
username = username
)
정말 바보같은 실수라 올리기 뭐하지만.. 누군가는 같은 실수를 하니까 ^^...
p.s. 에러 잡아주신 성준님께 무한 감사를..🙏
와우... 민젤.. 시간을 갈아넣은 정성스런 블로깅.. 잘봤습니다!
나도 전체적인 플로우 한번 정리해봐야겠네요!ㅋㅋㅋㅋ