장고 게시판(로그인, 로그아웃)

팔리동·2021년 7월 18일
1

장고 프로젝트

목록 보기
2/2

⭐️로그인& 로그아웃

장고 내장 User객체를 사용하지 않고 로그인 로그아웃 기능을 만들었다.
그리고 로그인 로직에 대해서 고민하고 성능 향상을 했다.

로그인

로그인 기능을 구현해 보았다.

def login(request):
    if 'user' in request.session:
        return redirect('index')
        
    if request.method == 'GET':
        return render(request, 'accounts/login.html')

    elif request.method == 'POST':
        error_message = {}
        userid = request.POST.get('user_id', None)
        password = request.POST.get('password', None)

        if not Accounts.objects.filter(user_id=userid).exists():
            error_message['error'] = '등록되지 않은 아이디 입니다.'
            return render(request, 'accounts/login.html', error_message)
            
        user = Accounts.objects.get(user_id=userid)

        if not check_password(password, user.password):
            error_message['error'] = '비밀번호를 틀렸습니다.'
            return render(request, 'accounts/login.html', error_message)
        
        request.session['user'] = user.user_id 

        return redirect('index')
  • 우선 세션을 활용해서 백엔드 단에서 로그인 여부를 확인하게 만들었다.
  • 이 로그인 기능을 구현하면서 jwt, 쿠키, 세션에 대해서 유튜브로 개념을 공부했다.
  • 일단 이 프로젝트에서 로그인 기능은 안전을 위해 세션을 사용하기로 했다.

GET & 로그인 상태일 경우

def login(request):
    if 'user' in request.session:
        return redirect('index')
        
    if request.method == 'GET':
        return render(request, 'accounts/login.html')
  • 로그인 뷰가 실행 됐을 때 가장 처음으로 세션에 로그인이 되었는지 확인을 하게한다.
    왜냐하면 프론트 단에서 로그인 상태이면 다시 로그인 페이지로 가는 바로가기가 안뜨고 로그아웃만 뜨게 만들거지만 사용자가 로그인 url을 알고 직접 접근할 수 있으므로 로그인url에 들어가면 맨 처음으로 세션을 확인해서 로그인 상태인지를 확인한다. 만약 로그인 상태면 index페이지로 리다이렉트 되게 했다.

  • 로그인 상태가 아니며 GET요청으로 접근하면 로그인 html을 렌더링 해준다.

로그인 로직

 elif request.method == 'POST':
        error_message = {}
        userid = request.POST.get('user_id', None)
        password = request.POST.get('password', None)

        if not Accounts.objects.filter(user_id=userid).exists():
            error_message['error'] = '등록되지 않은 아이디 입니다.'
            return render(request, 'accounts/login.html', error_message)
            
        user = Accounts.objects.get(user_id=userid)

        if not check_password(password, user.password):
            error_message['error'] = '비밀번호를 틀렸습니다.'
            return render(request, 'accounts/login.html', error_message)
        
        request.session['user'] = user.user_id 

        return redirect('index')
  • 로그인 로직은 입력값을 Accounts모델에 검색해서 없으면 '등록되지 않은 아이디 입니다.' 메시지를 넘겨주고 값이 있으면 user변수에 해당하는 값의 객체를 담고 비밀번호를 확인하게 짰다.

  • 역시나 짜면서도 뭔가 중복이 된다는 느낌을 받았고 이 포스팅을 쓰면서 문제점을 파악해보기로 했다.

  • 일단 세션확인하는 쿼리 한번은 무조건 있고

  • 그외 쿼리가 두번이나 실행이 된다.

  • 그것은 필터로userid가 존재하는지 확인할 때 한번 쿼리가 날라가고

  • userid에 해당하는 객체를 변수에 담을 때 한번 날린다.

  • 지금이야 0.3ms로 가능하지만 만약 회원수가 1000만개라면???? 행복회로 이지만
    쿼리문을 두번이나 날리는 건 효율이 떨어지니 수정을 했다.

  • 수정을 하면서 알게 됐지만 filter문에서 정보를 조회해서 컬럼값을 조회할 수 없어서 get을 써서 담으려고 했지만 get은 검색값이 없으면 에러값을 던져서 로직을 한번에 처리하는데 생각을 좀 했다.

수정된 로그인 로직

elif request.method == 'POST':
        try:
            error_message = {}
            userid = request.POST.get('user_id', None)
            password = request.POST.get('password', None)
            user = Accounts.objects.get(user_id=userid)
        except:
            error_message['error'] = '등록되지 않은 아이디 입니다.'
            return render(request, 'accounts/login.html', error_message)
        else:
            if not check_password(password, user.password):
                error_message['error'] = '비밀번호를 틀렸습니다.'
                return render(request, 'accounts/login.html', error_message)
        
        request.session['user'] = user.user_id 

        return redirect('index')
  • try except 문을 사용해서 user변수에 Accounts모델에서 입력받은 값을 get메소드로 조회하게 했다. 등록 된 아이디가 없으면 에러가 던져지므로 except문으로 '등록되지않은 아이디 입니다' 메시지를 넘겨준다.

  • 그리고 else문에서 비밀번호를 체킹하는데 user.password는 쿼리문을 날리지 않는다.

쿼리문이 두개로 줄어들었다.

로그아웃

def logout(request):
    if 'user' in request.session:
        del request.session['user']
        return redirect('index')
    return redirect('index')
  • 로그아웃 기능은 단순히 세션에 user를 키로 하는 값이 있으면 지워 버리고 인덱스 페이지로 리다이렉트하게 했다.
    없을 경우에는 그냥 리다이렉트 하게 했다.
  • 처음에는 조건문 없이 rmsid pop을 했는데 그럴때는 키 오류가 나서 조건문을 세워서 키가 있는지 확인한 후에 처리했다.

후기

  • 로그인 기능을 수정하면서 장고 orm에 대해서 조금 더 깊게 공부했다.
  • 이렇게 뭔가를 만들면서 내가 왜 코드를 이렇게 짰는지 고민하면서 정리하니까 배우는 게 많은 것 같다.
  • 다음은 카카오 소셜로그인이다.
profile
배움의 기록

0개의 댓글