2023/09/12 [TIL] django(장고) 비밀번호 변경 함수 : check_password

장현웅·2023년 9월 12일
0

1. 문제


현재 비밀번호 :
새 비밀번호 :
새 비밀번호 확인 :
변경하기

장고 프로젝트 중에 사용자 비밀번호를 바꾸는 기능을 구현하려고 했다.
로직은 이렇다.
만약 현재 비밀번호가 DB에 저장된 User 데이터의 비밀번호와 같다면, 그리고 새 비밀번호와 새 비밀번호 확인이 같다면 DB에 저장된 User 데이터의 비밀번호 값에 사용자가 입력한 새 비밀번호의 값을 저장해주자.

2. 시도


템플릿의 코드는 이렇다.

<form action="생략" method = "post">
{% csrf_token %}
<div>
	현재 비밀번호 : <input type="password" name="password">
</div>
<div>
	새 비밀번호 : <input type="password" name="new_password">
</div>
<div>
	새 비밀번호 확인 : <input type="password" name="new_password_check">
</div>
<button type="submit">변경하기</button>
</form>

views.py의 코드 로직은 이렇다.

def ___(request, user_id) :
	if request.method == "GET":
    	...
    elif request.method == "POST":
    	my_p = User.objects.get(id=user_id)	# DB User 테이블의 id값과 함수가 받은 인자 user_id 값이 같은 인스턴스(row) 데이터를 my_p라는 변수에 담는다.
        if request.POST['password'] == my_p.password:
        	if request.POST['new_password'] == request.POST['new_password_check']:
            	my_p.password = request.POST['new_password']
            	my_p.save()
        		return redirect(f'/profile/{my_p.id}/')
            else : 
            	...
   		else :
        	...
 	else:
    	...        

DB에서 가져온 User 인스턴스 데이터의 비밀번호와 사용자가 현재 비밀번호에 입력한 값이 같으면, 그리고 새 비밀번호에 입력된 값과 새 비밀번호 확인에 입력된 값이 같을 경우 DB에 있는 해당 User 데이터의 비밀번호 값을 사용자가 입력한 새 비밀번호로 저장한다.

결과는, 현재 비밀번호부터 같지 않다는 에러가 났다.

알아보니, DB에서 가져온 User 인스턴스 데이터의 비밀번호는 저장될 때 해싱처리되어 저장되기 때문에 그 해싱된 값과 비교해서 다르다는 결과가 나오는 것이다.

3. 해결


장고에는 비밀번호 변경을 위해 사용자가 입력한 비밀번호 값과 DB에 저장된 사용자의 비밀번호를 비교해주는 check_password라는 함수 기능이 있다.

check_password 함수는 두 개의 인자만을 받으며, 첫 번째 인자로는 사용자가 브라우저에서 입력한 값을 받고, 두 번째 인자로는 DB에 저장된 비밀번호 값을 받는다.

이 함수는 자동으로 이 두 인자 값을 비교하며 자동으로 'True면'이라는 조건을 부여한다.

코드로 나타내면 아래와 같다.

def ___(request, user_id):
    if request.method == "GET":
        my_password = User.objects.get(id=user_id)
        return render(request, 'password.html', {"tem_my_password": my_password})
    elif request.method == "POST":
        my_p = User.objects.get(id=user_id)
        if check_password(request.POST['password'], my_p.password):
            if request.POST['new_password'] == request.POST['new_password_check']:
                my_p.set_password(request.POST['new_password'])
                my_p.save()
                return redirect(f'/profile/{my_p.id}/')
            else:
                ...
        else:
            ...
    else:
        ...

check_password 함수가 두 인자 값을 비교해서 True이면 사용자가 입력한 '새 비밀번호'와 '새 비밀번호 확인'의 값을 비교하고, 이것이 True라면 가져온 인스턴스 데이터의 비밀번호에 set_password라는 함수로 사용자가 POST요청으로 보낸 새 비밀번호 값을 넣어주고, save()함수로 값을 저장한다.

4. 알게된 점


check_password : 장고에서 제공하는 함수로 받은 두 개의 인자를 비교해서 'True면'이라는 조건을 부여한다. 첫 번째 인자로는 사용자가 브라우저에서 입력한 값을 받고, 두 번째 인자로는 DB에 저장된 비밀번호 값을 받는다.

DB의 모델 데이터 인스턴스.set_password : 사용자가 입력한 새 비밀번호 값을 DB의 데이터에 지정

DB의 모델 데이터 인스턴스.save() : 새롭게 갱신된 데이터를 저장

받는 인자 값의 순서가 중요하다.

0개의 댓글