Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- 서버로그
- 타코트론
- intell
- 한빛미디어
- 로그남기기
- machinelearning
- 개발자회고
- 인하멘토링
- 우분투비트확인
- CrossAngle
- 2019회고
- 봉사활동
- 개발자를위한파이썬
- graphicdriver
- tacotron
- 쇠막대기
- 서구동구예비군훈련장
- 인천남중
- 인하대학교
- 노트북덮개
- jaypark.dating
- 결과를얻는법
- 놀이동산의슈퍼컴퓨터를작동시켜라
- 나는리뷰어다
- 신영준
- texttospeech
- Xangle
- 프로그래머스
- 프로그라피
- 심플소프트웨어
Archives
- Today
- Total
jc.jang
17강 중복 로그인 막기 본문
주제
- session을 이용해 중복 로그인을 막는다.
- 중복 로그인 시 middleware message로 사용자에게 알림 메시지를 노출한다.
노트
- 한 사용자가 A 브라우저에서 로그인 -> B 브라우저에서 로그인한 경우, A 브라우저의 세션을 종료 시킨다.
- django/contrib/auth/__init__(링크) 에서 보면 login 메소드는 로그인이 성공적으로 실행됐을 때, user_logged_in 시그널을 호출하는 것을 알 수 있다.
- 그렇다면 로그인 성공 시 user_logged_in 시그널을 호출하고 커스텀 리시버를 설정하여 기존에 연결된 세션을 끊어서 다중 로그인을 방지하자.
- 예전에 User 레코드 생성 시 Profile을 생성할 때 시그널을 사용했지만, 기억이 나지 않는다면 signals 공식문서(링크)를 참고하자.
- accounts/models.py
from django.conf import settings
from django.db import models
class UserSession(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, editable=False)
session_key = models.CharField(max_length=40, editable=False)
created_at = models.DateTimeField(auto_now_add=True)
- 현재 사용자의 세션을 저장하는 모델 객체 생성, (마이그레이션 필요)
- account/models.py
from django.conf import settings
from django.contrib.auth.signals import user_logged_in
from django.db import models
from importlib import import_module
SessionStore = import_module(settings.SESSION_ENGINE).SessionStore
def kicked_my_other_sessions(sender, request, user, **kwargs):
for user_session in UserSession.objects.filter(user=user):
session_key = user_session.session_key
session = SessionStore(session_key)
session.delete()
session_key = request.session.session_key
UserSession.objects.create(user=user, session_key=session_key)
user_logged_in.connect(kicked_my_other_sessions, dispatch_uid='user_logged_in')
- user_logged_in 시그널에 기존에 로그인한 세션을 삭제해주는 리시버를 연결해주자.
- 뷰가 아닌 곳에서 세션을 사용하려면 공식문서(링크)에 나와있는대로 SessionStore를 사용하면 된다.
- kicked_my_other_sessions 리시버를 만들었는데, 인자로 쓰이는 것들에 대해 알아보자.
- sender: 방금 로그인을 마친 유저의 클래스
- request: 현재 HttpRequest 인스턴스
- user: 방금 로그인을 마친 유저 인스턴스
- 따라서 함수에서 구현한 사항은
- 방금 로그인을 마친 유저가 가지고 있는 UserSession 클래스의 레코드를 모두 읽어온다.
- 세션을 삭제하여 로그아웃한다.
- 현재 세션에 대한 레코드를 생성하여 저장한다.
- 만약 중복 로그인을 통해 로그아웃된 경우, 사용자에게 메시지를 노출 시키고 싶다면?
- 프로젝트/settings.py
MIDDLEWARE = [
# ...
'django.contrib.messages.middleware.MessageMiddleware',
'accounts.middleware.KickedMiddleware',
# ...
]
- middleware를 추가한다.
- accounts/middleware.py
from django.conf import settings
from django.contrib import messages
from django.contrib.auth import logout as auth_logout
from django.shortcuts import redirect
from django.utils.deprecation import MiddlewareMixin
class KickedMiddleware(MiddlewareMixin):
def process_request(self, request):
kicked = request.session.pop('kicked', None)
if kicked:
messages.info(request, '동일 아이디로 다른 브라우저 웹사이트에서 로그인이 감지되어, 강제 로그아웃되었습니다.')
auth_logout(request)
return redirect(settings.LOGIN_URL)
- settings.py에 등록한 이름으로 클래스를 생성한다.
- 현재 세션에 'kicked'가 True면 메시지를 띄우고 로그아웃을한다.
- accounts/models.py
from django.conf import settings
from django.contrib.auth.signals import user_logged_in
from django.db import models
from importlib import import_module
SessionStore = import_module(settings.SESSION_ENGINE).SessionStore
def kicked_my_other_sessions(sender, request, user, **kwargs):
for user_session in UserSession.objects.filter(user=user):
session_key = user_session.session_key
session = SessionStore(session_key)
# session.delete()
session['kicked'] = True
session.save()
user_session.delete()
session_key = request.session.session_key
UserSession.objects.create(user=user, session_key=session_key)
user_logged_in.connect(kicked_my_other_sessions, dispatch_uid='user_logged_in')
- 미들웨어 추가에 따른 코드 변경이 필요하다.
- 기존에 로그인했던 세션(user_session)에 kicked = True를 할당한다.
- 원래 session middleware에서 save() 처리를 하는데, 지금은 middleware를 쓰지 않으니 직접 save를 호출 해야한다.
질문
- 쿠키와 세션에 대해 정리할 때가 온 것 같다...
- middleware를 처음 써봤는데 뭔지 잘 모르겠다
요약
- session을 확인하여 중복 로그인을 막을 수 있다.
날짜
- 오후 5시, 20190909
'Django > Django - 인증편' 카테고리의 다른 글
19강 프로필 수정 구현 (0) | 2019.09.09 |
---|---|
18강 SignupForm에 Meta.model 적용하기 (0) | 2019.09.09 |
16강 Permission 시스템을 통한 사용자 접근 제한하기 (2) | 2019.09.09 |
15강 User Admin 커스텀하기 (0) | 2019.09.08 |
14강 커스텀 User Model 만들기 (0) | 2019.09.05 |
Comments