Open Spiraline opened 5 years ago
1 로그인을 하고 response를 확인해보면 session_id와 항께 csrf token이 새로 나오는데 그 새로운 토큰을 쓰시면 됩니다
2, 3. 네 일단 3번의 문제는 AnonymousUser 의 문제로 인한 것 같구요 일단 signin 함수 자체의 문제는 없어 보여서 (뭐 그래도 모르니 계속 확인은 부탁드립니다)
다른 view에서 request 보냈을 때 user가 제대로 있는지를 계속 확인해보셔야 할 것 같습니다
저게 anonymousUser로 되는 이유는
auth 관련 middleware가
settings.py
에
'django.contrib.auth.middleware.AuthenticationMiddleware',
가 있는데
이 코드가
class AuthenticationMiddleware(MiddlewareMixin):
def process_request(self, request):
assert hasattr(request, 'session'), (
"The Django authentication middleware requires session middleware "
"to be installed. Edit your MIDDLEWARE%s setting to insert "
"'django.contrib.sessions.middleware.SessionMiddleware' before "
"'django.contrib.auth.middleware.AuthenticationMiddleware'."
) % ("_CLASSES" if settings.MIDDLEWARE is None else "")
request.user = SimpleLazyObject(lambda: get_user(request))
에서 request의 user attribute를 get_user
의 결과값으로 넣어주거든요
get_user
함수를 보시면
def get_user(request):
"""
Return the user model instance associated with the given request session.
If no user is retrieved, return an instance of `AnonymousUser`.
"""
from .models import AnonymousUser
user = None
try:
user_id = _get_user_session_key(request)
backend_path = request.session[BACKEND_SESSION_KEY]
except KeyError:
pass
else:
if backend_path in settings.AUTHENTICATION_BACKENDS:
backend = load_backend(backend_path)
user = backend.get_user(user_id)
# Verify the session
if hasattr(user, 'get_session_auth_hash'):
session_hash = request.session.get(HASH_SESSION_KEY)
session_hash_verified = session_hash and constant_time_compare(
session_hash,
user.get_session_auth_hash()
)
if not session_hash_verified:
request.session.flush()
user = None
return user or AnonymousUser()
여기서 user가 None
이면 AnonymousUser()
를 리턴하게 되어 있는데
session hash verified가 안 되어서 None
이 되는 경우가 있어서 이와 관련하여 ARC에서 문제가 있을수도 있다고 생각이 됩니다.
3번 같은 경우에는 사실 한 가지 팁을 드리면
token을 가져오는 test를 따로 두시고
test client에서는 csrf_check
을 False
로 두시고 하는 방법이 있습니다.
참고로 말씀드리면, session id를 헤더에 넣을 때 반드시 세미콜론(;)을 붙여 주셔야 됩니다. 이것 때문일 수 있으니 한 번 확인해 보세요.
2번의 문제의 경우에는 @kyunggeun-lee 말씀대로 세미콜론을 붙이니 request.user가 user의 이름으로 출력되는 것을 확인하였습니다! 3번의 test의 경우 csrf_check를 False로 해놔도 authenticate에서 None을 return하여 확인해보니
User.objects.create_user('user1', 'email', 'pw1')
와 같이 create_user에서 email parameter를 넣어야 한다는 것을 확인했고 해당 방법으로 해결하였습니다! 그런데 그렇다면 views.py의 스켈레톤에서
def signup(request):
if request.method == 'POST':
req_data = json.loads(request.body.decode())
username = req_data['username']
password = req_data['password']
User.objects.create_user(username, password)
return HttpResponse(status=201)
else:
return HttpResponse(status=405)
의 User.objects.create_user(username, password)
에 이메일에 해당하는 argument가 추가되어야 할 듯 한데 제가 이해한 바가 맞을까요?
두 분 모두 답변 너무 감사드립니다!
음 우선 email field가 optional인데 그걸 했다고 되었다니 신기하네요 https://docs.djangoproject.com/en/2.2/ref/contrib/auth/#django.contrib.auth.models.User.email 일단은 email 없이도 되는 게 맞아서 한 번 다시 확인해 보시는 걸 추천드리겠습니다
User.objects.create_user('user1', 'pw1')
를 하게 되면 인자 전달 순서때문에 'pw1'
이 user.email
로 가는 것 같은데
User.objects.create_user(username='user1', password='pw1')
처럼
필드를 명확하게 주면 이메일이 없어도 정상적으로 생성되는것으로 보입니다!
@lllY2Klll 그런 이유였군요 문서를 읽어보니
create_user(username, email=None, password=None, **extra_fields)
인 것을 보니 email과 password가 모두 optional인 듯 하여 말씀하신대로 두 개만 쓴다면 password가 email에 저장되는 것 같습니다! 문제는 해결이 되었으나 이유에 대해 궁금했는데 알게 되었네요 감사합니다!
안녕하세요 조교님 항상 수고하십니다.
HW3을 진행하는 과정에서 인증 관련해서 문제가 생겨서 질문드립니다.
1) signin 관련 view를 작성한 뒤 ARC.pdf에 있는 내용대로 따라했을 때 토큰을 받고 토큰을 이용해 POST /api/signin/ 까지는 성공했으나 이후 POST /api/aritlces의 헤더에 해당 sessionid를 넣고 실행을 했을 때에는 CSRF 인증 오류 (403)가 발생합니다. 이 때의 CSRF token은 다시 GET /api/token/을 통해서 받아온 token이어야 하나요? 아니면 POST /api/aritlce/ 의 response에서도 CSRF token이 존재하는데 이 토큰을 사용해야 하나요?
2) 1번의 두 방법 모두 signin까지는 response status 204를 받으며 성공적으로 기능을 했으나 POST /api/aritlce/ 에서 401 Response를 보였는데요. post에서 request.user를 출력해보니 AnonymousUser가 출력되는 것을 확인할 수 있었습니다. 따라서 로그인이 제대로 되지 않았다고 판단했는데요. views.py 내의 signin 함수는 link를 참고하여 아래와 같이 구현했습니다.
signin까지는 성공했으나 이후 다른 api를 실행할 때에 request.user가 AnonymousUser가 뜨는 것은 어느 방향에서 코드를 수정해야 할까요?
3)
해당 signin에 대해서 위의 테스트 코드를 작성해보았으나 이 역시 401 Response를 보이며 test가 fail되는 것을 확인할 수 있었습니다. 2번에서 언급한대로 ARC를 이용한 POST /api/signin/ 는 성공했으나 테스트 코드는 통과하지 못한 것이 의아했는데 혹시 2번에서의 signin 이후에도 request.user가 AnonymousUser로 출력되는 것과 연관이 있을까요?
감사합니다.