6. 그래프 API

그래프API 정보를 가져오기 위해 사용한다.

  • 노드 : 기본적으로 사용자, 사진, 페이지, 댓글과 같은 “항목”입니다.
  • 에지 : 페이지의 사진, 사진의 댓글 등 “항목” 간의 연결입니다.
  • 필드 : 생일, 페이지의 이름 등 “항목”에 대한 정보입니다.
GET graph.facebook.com
  /{node-id}

관련 링크

7. Custom backends 인증 시스템

페이스북 가입시 이메일은 필수 값이 아니다. 그러니 user id를 사용하자.

페이스북 인증 시, 비밀번호를 요구하지 않는다. 하지만 장고는 비밀번호가 반드시 필요하다. 그러므로 커스텀 백엔드 인증시스템을 만들어야 한다.

Authentication backends 

username/password 방식이 아닌 다른 방식으로 사용할 때, 확장하거나 대체할 수 있는 Authentication backends 제공한다.

Specifying authentication backends

장고는 인증을 체크하는 authentication backends 리스트를 유지한다. django.contrib.auth.authenticate()를 호출하면, 장고는 authentication backends 리스트에 있는 모든 인증을 시도한다. 만약 첫번째 인증 방법이 실패하면 장고는 모든 backends를 시도할 때 까지 두번째, 그 다음 시도를 한다.

authentication backends 리스트는 AUTHENTICATION_BACKENDS 설정에 지정한다.

# 기본 인증 백엔드
['django.contrib.auth.backends.ModelBackend']

AUTHENTICATION_BACKENDS 순서는 중요하다. 만약 같은 username/password가 여러 backends에서 유효하다면, 장고는 처음 매치된 시점에서 처리를 멈춘다.

Writing an authentication backend

인증 백엔드는 get_user(user_id)authenticate(** credentials)의 두 가지 필수 메소드가 있다.

  • get_user : user_id를 취하고 사용자 객체를 반환
  • authenticate : 자격 증명(credentials)을 키워드 인자로 사용
class MyBackend(object):
    def authenticate(self, token=None):
        # Check the token and return a user.
        # 알아서 처리 후
        # 유효하면 반드시 사용자 객체를 반환하고
        # 아니면 None을 반환

authenticate()는 자격 증명이 유효한지 확인한 다음 자격 증명이 유효하면 해당 자격 증명과 일치하는 사용자 객체를 반환해야합니다. 유효하지 않으면 없음을 반환해야합니다.

8. Beckend구성

페이스북 인증 로그인으로 회원가입을 받을 경우 두 가지 케이스가 있다.

  • 인증완료 후 바로 사용가능 한 경우 > 바로 가입
  • 인증 후 나머지 필드를 채워야 사용가능 한 경우 > 추가 정보(나머지 필드)를 받고 가입

바로 가입하는 벡엔드를 구성해본다.

# member/beckends.py
from member.models import MyUser


class FacebookBackend():
    # 있으면 가져오고 아니면 인증하는 과정을 작성
    def authenticate(self, facebook_id, **extra_fields):
        user, user_created = MyUser.objects.get_or_create(
            username=facebook_id
        )
        return user

    def get_user(self, user_id):
        try:
            return MyUser.objects.get(id=user_id)
        except MyUser.DoesNotExist:
            return None

# member/views.py
def login_facebook(request):
        # ...
        # 페이스븍 USER_ID만으로 인증
        user = authenticate(facebook_id=USER_ID)
        login(request, user)
        return redirect('index')


def logout_fbv(request):
    logout(request)
    return redirect('index')
# facebook/settings.py
AUTHENTICATION_BACKENDS = [
    'django.contrib.auth.backends.ModelBackend',
    'member.backends.FacebookBackend'
]

슈퍼유저 생성 후 admin 사이트에 접속해본다. 유저가 정상적으로 가입한 것을 확인할 수 있다.

9. 유저 프로필 이미지 추가

graph-api: reference user picture

class FacebookBackend():
    def authenticate(self, facebook_id, extra_fields=None):
        # 프로필 이미지를 가져오는 기능 추가
        url_profile = 'https://graph.facebook.com/{user_id}/picture'.format(
            user_id=facebook_id,
        )
        params = {
            'type': 'large',
            'width': '500',
            'height': '500',
        }

        # 메모리상에 임시파일 생성
        temp_file = NamedTemporaryFile(delete=False)

        # stream=True는 조각단위로 다운받음
        r = requests.get(url_profile, params, stream=True)

        # 요청하는 URL에서 파일 확장자를 가져옴,
        # 확장자랑 앞에 있는 이름을 구분해줌
        _, file_ext = os.path.splitext(r.url)

        # 확장자 저장 , .과 ? 사이만 가져옴 = 확장자
        file_ext = re.sub(r'(\.[^?]+).*', r'\1', file_ext)
        file_name = '{}{}'.format(
            facebook_id,
            file_ext
        )
        for chunk in r.iter_content(1024):
            temp_file.write(chunk)

        # facebooi_id가 username인 경우 MyUser를 갖고 오거나
        # defaults값을 이용해서 지정
        defaults = {
            'first_name': extra_fields.get('first_name', ''),
            'last_name': extra_fields.get('last_name', ''),
            'email': extra_fields.get('email', ''),
        }
        user, user_created = MyUser.objects.get_or_create(
            defaults=defaults,
            username=facebook_id
        )
        user.img_profile.save(file_name, File(temp_file))
        return user
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            TEMPLATE_DIR,
        ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                # MEDIA_URL 변수 사용
                'django.template.context_processors.media',
                ]
            }
      }
]

문자보내기

cool sms를 이용해 문자 보내는 실습을 한다.

pip install coolsms_python_sdk

과제

  • 페이스북 코멘트로 점수매겨서 가장 반응 좋은 친구 찾기
  • 이메일 보내기