Django-rest-framework: ์˜ค๋ฅ˜ 'WSGIRequest' ๊ฐœ์ฒด์— 'successful_authenticator' ์†์„ฑ์ด ์—†์Šต๋‹ˆ๋‹ค.

์— ๋งŒ๋“  2013๋…„ 06์›” 06์ผ  ยท  4์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: encode/django-rest-framework

์ƒˆ ์ธ์ฆ ๋ฐฉ๋ฒ•์„ ๊ตฌํ˜„ํ•˜๊ณ  IsAuthenticated ๊ถŒํ•œ์œผ๋กœ ๋ทฐ๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์‚ฌ์šฉ์ž๊ฐ€ ์ธ์ฆ๋˜์ง€ ์•Š์œผ๋ฉด django rest ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ๋‹ค์Œ์„ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.

  File "XXX/site-packages/rest_framework/views.py", line 206, in check_permissions
    self.permission_denied(request)
  File "XXX/site-packages/rest_framework/views.py", line 80, in permission_denied
    if not self.request.successful_authenticator:
  File "XXX/site-packages/rest_framework/request.py", line 362, in __getattr__
    return getattr(self._request, attr)
AttributeError: 'WSGIRequest' object has no attribute 'successful_authenticator'

์ฝ”๋“œ๋ฅผ ๋ณด๋‹ˆ ์ž˜๋ชป๋œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. " self.request .successful_authenticator"๋Š” ์–ด๋””์— ์žˆ์Šต๋‹ˆ๊นŒ? ์ €๋Š” " request .successful_authenticator"์—ฌ์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

80ํ–‰ ๊ทผ์ฒ˜์˜ Views.py.

def permission_denied(self, request):
    """
    If request is not permitted, determine what kind of exception to raise.
    """
    if not self.request.successful_authenticator:
        raise exceptions.NotAuthenticated()
    raise exceptions.PermissionDenied()

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

Google์„ ํ†ตํ•ด ์ด ๋ฌธ์ œ์— ๋„๋‹ฌํ•˜๋Š” ๋‹ค๋ฅธ ์‚ฌ๋žŒ์„ ์œ„ํ•ด...

์˜ค๋ฅ˜์˜ ์›์ธ์— ๋Œ€ํ•œ ๋‹จ์„œ๋Š” WSGIRequest successful_authenticator ์†์„ฑ์ด ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ DRF ์ฝ”๋“œ์—์„œ์ด ์‹œ์ ์—์„œ ์šฐ๋ฆฌ๋Š” ์ฒ˜๋ฆฌํ•ด์•ผ rest_framework.request.Request ๋ณด๋‹ค๋Š” ๋ฒ ์–ด WSGIRequest .

๊ทธ๋ฆฌ๊ณ  ์‹ค์ œ๋กœ pdb๋ฅผ ํ†ตํ•ด ์ฝ”๋“œ๋ฅผ ์ž…๋ ฅํ•˜๋ฉด WSGIRequest๊ฐ€ ์•„๋‹Œ DRF ์š”์ฒญ์ด ์žˆ์Œ์„ ์•Œ๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ฌธ์ œ๋Š” request.Request ์— @property ๋ฐ์ฝ”๋ ˆ์ดํŒ…๋œ ๋ฉ”์„œ๋“œ( user , successful_authenticator ๋“ฑ)๊ฐ€ ๋งŽ์ง€๋งŒ __getattr__ ๋ฉ”์„œ๋“œ.

์–ด๋–ค ์†์„ฑ์˜ ์ฝ”๋“œ๊ฐ€ AttributeError ๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•˜๋ฉด Python์€ ๋Œ€์‹  __getattr__ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๊ถ๊ทน์ ์œผ๋กœ attr(์†์„ฑ๊ณผ ๋™์ผํ•œ ์ด๋ฆ„์„ ๊ฐ€์ง„ ์†์„ฑ์„ ์ฐพ์œผ๋ ค๊ณ  ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค. ์˜ค๋ฅ˜) ์ž์‹ WSGIRequest ๊ฐœ์ฒด์—์„œ.

์ด๊ฒƒ์ด 'WSGIRequest' object has no attribute 'successful_authenticator' ๋˜๋Š” 'WSGIRequest' object has no attribute 'user' ์™€ ๊ฐ™์€ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค(ํ›„์ž๋Š” ๋ฌผ๋ก  Django AuthenticationMiddleware๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ์—๋งŒ).

์ œ ๊ฒฝ์šฐ์— AttributeError๋Š” @successful_authenticator ์†์„ฑ์— ์ฒ˜์Œ ์•ก์„ธ์Šคํ•  ๋•Œ ์ฐจ๋ก€๋กœ ํ˜ธ์ถœ๋˜๋Š” authentication_classes ... ์ค‘ ํ•˜๋‚˜์—์„œ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. Request ํด๋ž˜์Šค์˜ ์†์„ฑ๊ณผ __getattr__ ์˜ ์กฐํ•ฉ์€ ์˜ค๋ฅ˜์˜ ์‹ค์ œ ์†Œ์Šค๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ๋งˆ์Šคํ‚นํ•ฉ๋‹ˆ๋‹ค.

๋ชจ๋“  4 ๋Œ“๊ธ€

์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค, ์ œ ์ฝ”๋“œ์—์„œ ๊ฐ™์€ ์‹ค์ˆ˜๋ฅผ ์ €์งˆ๋ €์Šต๋‹ˆ๋‹ค!!!

Google์„ ํ†ตํ•ด ์ด ๋ฌธ์ œ์— ๋„๋‹ฌํ•˜๋Š” ๋‹ค๋ฅธ ์‚ฌ๋žŒ์„ ์œ„ํ•ด...

์˜ค๋ฅ˜์˜ ์›์ธ์— ๋Œ€ํ•œ ๋‹จ์„œ๋Š” WSGIRequest successful_authenticator ์†์„ฑ์ด ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ DRF ์ฝ”๋“œ์—์„œ์ด ์‹œ์ ์—์„œ ์šฐ๋ฆฌ๋Š” ์ฒ˜๋ฆฌํ•ด์•ผ rest_framework.request.Request ๋ณด๋‹ค๋Š” ๋ฒ ์–ด WSGIRequest .

๊ทธ๋ฆฌ๊ณ  ์‹ค์ œ๋กœ pdb๋ฅผ ํ†ตํ•ด ์ฝ”๋“œ๋ฅผ ์ž…๋ ฅํ•˜๋ฉด WSGIRequest๊ฐ€ ์•„๋‹Œ DRF ์š”์ฒญ์ด ์žˆ์Œ์„ ์•Œ๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ฌธ์ œ๋Š” request.Request ์— @property ๋ฐ์ฝ”๋ ˆ์ดํŒ…๋œ ๋ฉ”์„œ๋“œ( user , successful_authenticator ๋“ฑ)๊ฐ€ ๋งŽ์ง€๋งŒ __getattr__ ๋ฉ”์„œ๋“œ.

์–ด๋–ค ์†์„ฑ์˜ ์ฝ”๋“œ๊ฐ€ AttributeError ๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•˜๋ฉด Python์€ ๋Œ€์‹  __getattr__ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๊ถ๊ทน์ ์œผ๋กœ attr(์†์„ฑ๊ณผ ๋™์ผํ•œ ์ด๋ฆ„์„ ๊ฐ€์ง„ ์†์„ฑ์„ ์ฐพ์œผ๋ ค๊ณ  ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค. ์˜ค๋ฅ˜) ์ž์‹ WSGIRequest ๊ฐœ์ฒด์—์„œ.

์ด๊ฒƒ์ด 'WSGIRequest' object has no attribute 'successful_authenticator' ๋˜๋Š” 'WSGIRequest' object has no attribute 'user' ์™€ ๊ฐ™์€ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค(ํ›„์ž๋Š” ๋ฌผ๋ก  Django AuthenticationMiddleware๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ์—๋งŒ).

์ œ ๊ฒฝ์šฐ์— AttributeError๋Š” @successful_authenticator ์†์„ฑ์— ์ฒ˜์Œ ์•ก์„ธ์Šคํ•  ๋•Œ ์ฐจ๋ก€๋กœ ํ˜ธ์ถœ๋˜๋Š” authentication_classes ... ์ค‘ ํ•˜๋‚˜์—์„œ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. Request ํด๋ž˜์Šค์˜ ์†์„ฑ๊ณผ __getattr__ ์˜ ์กฐํ•ฉ์€ ์˜ค๋ฅ˜์˜ ์‹ค์ œ ์†Œ์Šค๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ๋งˆ์Šคํ‚นํ•ฉ๋‹ˆ๋‹ค.

DRF ๋ณด๊ธฐ์— ๋ถ€์ ์ ˆํ•œ authentication_classes (์‹ค์ˆ˜๋กœ ๋‹ค๋ฅธ ๋‚˜๋จธ์ง€ API ํ”„๋ ˆ์ž„์›Œํฌ์— ๋Œ€ํ•œ ๋ ˆ๊ฑฐ์‹œ ์ธ์ฆ ํด๋ž˜์Šค)๊ฐ€ ์žˆ์„ ๋•Œ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์–ธ์  ๊ฐ€ ํŒŒ์ด์ฌ์ด ํƒ€์ž…์„ธ์ดํ”„๋˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค :)

์ฐธ๊ณ ๋กœ djangorestframework-expiring-authtoken < 0.1.4 ๋กœ DRF๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ๋‹ค์Œ ๋ฌธ์ œ๋กœ ์ธํ•ด ์ด ์˜ค๋ฅ˜๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.
https://github.com/JamesRitchie/django-rest-framework-expiring-tokens/issues/11

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰