회원가입 흐름
회원가입시 클라이언트와 서버사이에 어떤 흐름이 발생하는가?
클라이언트에서 회원가입에 대한 정보가 보내진다.
이메일, 패스워드, 개인정보 등
http통신을 통해 json형태로 데이터가 보내진다.
서버측에서 파이썬이 사용가능한 형태로 데이터를 변환시킨다.
json.loads()를 이용해서 딕셔너리 형태로 변환시킨다.
여기서 키값이 올바르게 들어오지 않은 경우 keyerror가 발생한다.
각각의 데이터에 대한 오류확인을 후 이상이 없을 시 데이터베이스에 저장한다.
서버 측에서 클라이언트 측에 성공메시지를 보낸다.
로그인 흐름
클라이언트 측에서 아이디와 패스워드를 http통신을 이용해서 보낸다.
서버에선 들어온 정보와 데이터베이스에 저장된 정보가 같은지 판단한다.
같다면 로그인 성공, 틀리다면 오류를 발생시킨다.
클라이언트와 서버의 연결
아직 우리는 도메인을 가지고 있지 않다.
그러므로 서버측의 IP Address를 클라이언트 측에 알려주어 접속을 하게 한다.
ipconfig getifaddr en0
맥에서 자신의 무선 아이피 주소를 확인ipconfig getifaddr en0
맥에서 자신의 유선 아이피 주소를 확인Curl ifconfig.me
맥에서 자신의 public IP Address 확인예시)
http://아이피 주소:포트번호/프로젝트url주소/앱usl주소
회원가입
http://10.5.123.12:8000/user/signup
로그인
http://10.5.123.12:8000/user/login
클라이언트 쪽에서 위에 예시로 들은 아이피 주소로 접속시 서버가 열려있다면 작업이 가능하다.
모델링 user/models.py
from django.db import models
class User(models.Model):
name = models.CharField(max_length=100)
email = models.CharField(max_length=100, unique=True)
password = models.CharField(max_length=100)
phone_number = models.CharField(max_length=100, unique=True)
create_at = models.DateTimeField(auto_now_add=True)
update_at = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'users'
회원가입 user/viesw.py/UserView()
class UserView(View):
def post(self, request):
try:
data = json.loads(request.body)
name = data["name"]
email = data["email"]
password = data["password"]
phone_number = data["phone_number"]
regx_email = '^[a-zA-Z0-9+-_.]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$'
regx_password = '^(?=.*[A-Za-z])(?=.*\d)(?=.*[$@$!%*#?&])[A-Za-z\d$@$!%*#?&]{8,}$'
regx_phone_number = '^\d{3}-\d{3,4}-\d{4}$'
json.loads(request.body)
를 이용해서 http통신 시 post를 통해 들어오는 request의 json데이터를 파이썬에 맞는 딕셔너리 형태로 변경해준다.
data["키"]를 이용해서 키에 대한 값을 변수에 저장한다.
정규식에 해당하는 패턴을 정의해 준다.
check_email_regx(regx_email, email)
if User.objects.filter(email = email).exists():
raise ValueError("EXISTED_EMAIL")
check_password_regx(regx_password, password)
check_phone_regx(regx_phone_number, phone_number)
if User.objects.filter(phone_number = phone_number).exists():
raise ValueError("EXISTED_PHONE-NUMBER")
hashed_password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
User.objects.create(
name = name,
email = email,
password = hashed_password,
phone_number = phone_number,
)
return JsonResponse({"message": "SUCCESS"}, status=201)
except KeyError:
return JsonResponse({"message": "KEY_ERROR"}, status=400)
except ValueError as e:
return JsonResponse({"message": f"{e}"}, status=400)
def check_email_regx(pattern, field_data):
if not re.compile(pattern).match(field_data):
raise ValueError("INVILD_EMAIL")
def check_password_regx(pattern, field_data):
if not re.compile(pattern).match(field_data):
raise ValueError("INVILD_PASSWORD")
def check_phone_regx(pattern, field_data):
if not re.compile(pattern).match(field_data):
raise ValueError("INVILD_PHONE-NUMBER")
로그인 user/viesw.py/LoginView()
로그인을 하기 위해서는 로그인에 대한 정보가 들어있는 데이터베이스와 서버가 통신을 해서 아이디와 비밀번호를 가지고 오고, 클라이언트로 부터 http통신을 통해 json으로 들어온 데이터의 아이디와 비밀번호가 같은지 판단을 해서, 그 결과를 응답해 주면 된다.
만약 로그인에 성공한 경우 response에 토큰을 함께 보내서, 통신의 stateless 속성에 대해서 이후에도 통신이 가능하게 한다.
class LoginView(View):
def post(self, request):
try:
data = json.loads(request.body)
email = data["email"]
password = data["password"]
user = User.objects.get(email = email)
if not bcrypt.checkpw(password.encode('utf-8'), user.password.encode('utf-8')):
return JsonResponse({"message": "INVILD_USER"}, status=400)
access_token = jwt.encode({"id": user.id}, settings.SECRET_KEY, settings.ALGORITHM)
return JsonResponse({
"message": "SUCCESS",
"access_token": access_token
}, status=200)
get()함수를 이용해서 해당 유저를 변수에 저장해준다.
패스워드 저장시 hash로 저장된 데이터를 유저에게서 들어온 패스워드를 비교해준다.
만약 패스워드가 맞다면 jwt를 이용해서 토큰을 발급해준다.
jwt.encode({"id": user.id}, settings.SECRET_KEY, settings.ALGORITHM)
except User.DoesNotExist :
return JsonResponse({"message": "DOES_NOT_EXIST"}, status=401)
except KeyError:
return JsonResponse({"message": "KEY_ERROR"}, status=400)
westagram/urls.py
어느 app을 호출할 것인지를 결정해준다.
from django.urls import path, include
urlpatterns = [
path("user", include("users.urls")),
]
user/urls.py
app 중에서 어느 view를 호출 할 것인지를 결정한다.
from django.urls import path
from .views import UserView, LoginView
urlpatterns = [
path("/signup",UserView.as_view()),
path("/login", LoginView.as_view()),
]
그 이외
위의 코드 이외에 westagram/settings.py에서 설정을 바꾸어 주어야 하며,
my_settings.py에서 시크릿키, 데이터베이스, 알고리즘 등의 설정도 이루어져야 한다.