class GithubLogin(APIView):
permission_classes = [AllowAny]
def get(self, request):
github_oauth_url = "https://github.com/login/oauth/authorize"
params = {
"client_id": GITHUB_CLIENT_ID,
"redirect_uri": GITHUB_REDIRECT_URI,
"scope": "read:user",
"user:email" "state": "state_parameter", # CSRF 방지용 state 값
}
# GitHub로 리디렉션
auth_url = f"{github_oauth_url}?{urlencode(params)}"
return redirect(auth_url)
class GitHubLoginCallback(APIView):
permission_classes = [AllowAny]
def get(self, request, *args, **kwargs):
# GitHub에서 받은 인증 코드
code = request.GET.get("code")
# 인증 코드가 없으면 에러 반환
if not code:
return Response({"error": "Authorization code not provided"}, status=400)
# GitHub 토큰 엔드포인트
token_endpoint_url = "https://github.com/login/oauth/access_token"
# POST 요청으로 액세스 토큰 요청
response = requests.post(
url=token_endpoint_url,
headers={"Accept": "application/json"},
data={
"client_id": GITHUB_CLIENT_ID,
"client_secret": GITHUB_CLIENT_SECRET,
"code": code,
"redirect_uri": GITHUB_REDIRECT_URI,
},
)
# 응답을 JSON 형식으로 파싱
try:
token_data = response.json()
access_token = token_data.get("access_token")
if not access_token:
return Response({"error": "Access token not received"}, status=400)
# GitHub 사용자 정보 가져오기
user_info_url = "https://api.github.com/user"
headers = {"Authorization": f"Bearer {access_token}"}
response = requests.get(user_info_url, headers=headers)
response_data = response.json()
email = response_data["email"]
address = email.split("@")
id = address[0] + address[1][0] + address[1][1]
username = f"07_{id}"
try:
user = User.objects.get(username=username)
print("가입된 사용자")
except User.DoesNotExist:
print("미가입된 사용자")
user = User.objects.create(
username=username,
email=f"{id}@social.com",
first_name="Anonymous",
nickname=id,
is_active=True,
is_social=True,
)
user.save()
user.social_login = True
user.save()
username = user.username
return Response({"username": username})
except requests.exceptions.RequestException as e:
return Response({"error": f"Request error: {str(e)}"}, status=400)
except ValueError:
return Response({"error": "Invalid response from Google"}, status=400)