質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Next.js

Next.jsは、Reactを用いたサーバサイドレンダリングなどを行う軽量なフレームワークです。Zeit社が開発しており、nextコマンドでプロジェクトを作成することにより、開発環境整備が整った環境が即時に作成できます。

Vercel

Vercelとは、フロントエンド開発向けのフレームワークです。静的サイトとサーバレス機能のためのクラウドプラットフォームで、簡単にWebサイトやWebサービスをデプロイできます。自動でスケールでき、監視や各種設定も必要ありません。

Heroku

HerokuはHeroku社が開発と運営を行っているPaaSの名称です。RubyやNode.js、Python、そしてJVMベース(Java、Scala、Clojureなど)の複数のプログラミング言語をサポートしている。

Q&A

解決済

1回答

4065閲覧

Next.jsでCookieがセットされない

satoh23

総合スコア1

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Next.js

Next.jsは、Reactを用いたサーバサイドレンダリングなどを行う軽量なフレームワークです。Zeit社が開発しており、nextコマンドでプロジェクトを作成することにより、開発環境整備が整った環境が即時に作成できます。

Vercel

Vercelとは、フロントエンド開発向けのフレームワークです。静的サイトとサーバレス機能のためのクラウドプラットフォームで、簡単にWebサイトやWebサービスをデプロイできます。自動でスケールでき、監視や各種設定も必要ありません。

Heroku

HerokuはHeroku社が開発と運営を行っているPaaSの名称です。RubyやNode.js、Python、そしてJVMベース(Java、Scala、Clojureなど)の複数のプログラミング言語をサポートしている。

0グッド

0クリップ

投稿2021/07/16 07:50

編集2021/07/16 11:22

前提・実現したいこと

現在フロントとバックエンドのサーバーを分けてWebアプリを作成しています
既にデプロイ済みです
○バックエンド○
・Django + Heroku
○フロントエンド○
・Next.js + Vercel

Herokuは無料のものを使っています

よろしくお願いします

発生している問題・エラーメッセージ

ログイン時に返ってきたクッキーをブラウザにセットしたいです
実際はsetCookie属性が付いたレスポンスが返ってきているにもかかわらずブラウザにCookieがセットされていません

ログイン時のログ(一部)

Heroku

12021-07-16T10:03:08.590609+00:00 heroku[router]: at=info method=POST path="/api/v1/token-refresh/" host=www.tyoitasi.com request_id=26c4d377-4507-44df-a041-9b5aa88b4442 fwd="2400:4052:e20:2f00:50b:f8fb:bd08:3843,172.68.118.61" dyno=web.1 connect=2ms service=5031ms status=500 bytes=107800 protocol=https 22021-07-16T10:03:10.314311+00:00 heroku[router]: at=info method=POST path="/api/v1/login/" host=www.tyoitasi.com request_id=d6bfc715-22e6-428c-b8da-20e274de2a1d fwd="2400:4052:e20:2f00:50b:f8fb:bd08:3843,172.68.118.61" dyno=web.1 connect=0ms service=6757ms status=200 bytes=3443 protocol=https 32021-07-16T10:03:10.315683+00:00 app[web.1]: 10.41.200.163 - - [16/Jul/2021:19:03:10 +0900] "POST /api/v1/login/ HTTP/1.1" 200 1257 "https://project-tyoitasi.vercel.app/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36" 42021-07-16T10:03:10.841532+00:00 heroku[router]: at=info method=GET path="/api/v1/get-list-article/" host=www.tyoitasi.com request_id=5796fd55-9b7f-4f0e-b111-a6e4f60907a2 fwd="2400:4052:e20:2f00:50b:f8fb:bd08:3843,172.68.118.61" dyno=web.1 connect=1ms service=79ms status=200 bytes=387 protocol=https

ログインリクエストに対するレスポンスヘッダー
2
1

該当のソースコード

Next

1export async function login(email: string, password: string) { 2 let isSuccess: boolean = false; 3 await fetch(`${process.env.NEXT_PUBLIC_RESTAPI_URL}api/v1/login/`, { 4 method: "POST", 5 body: JSON.stringify({ email: email, password: password }), 6 headers: { 7 "Content-Type": "application/json", 8 }, 9 credentials: "include", 10 }).then((res) => { 11 if (res.status === 400) { 12 isSuccess = false; 13 } else if (res.ok) { 14 isSuccess = true; 15 } 16 }); 17 window.location.reload(); 18 return isSuccess; 19}

Django

1from dj_rest_auth.app_settings import (JWTSerializer, 2 JWTSerializerWithExpiration, 3 TokenSerializer, create_token) 4from dj_rest_auth.models import TokenModel 5from dj_rest_auth.views import sensitive_post_parameters_m 6from dj_rest_auth.utils import jwt_encode 7from django.conf import settings 8from django.contrib.auth import login as django_login 9from django.utils import timezone 10from rest_framework import status 11from rest_framework.generics import GenericAPIView 12from rest_framework.permissions import AllowAny 13from rest_framework.response import Response 14import datetime 15 16from accounts.serializers import CustomLoginSerializer 17 18def set_userid_cookies(response): 19 userid = response.data['user']['id'] 20 max_age = 24 * 60 * 60 21 expires = datetime.datetime.strftime( 22 datetime.datetime.utcnow() + datetime.timedelta(seconds=max_age), 23 "%a, %d-%b-%Y %H:%M:%S GMT", 24 ) 25 26 response.set_cookie( 27 'UID', 28 userid, 29 max_age=max_age, 30 expires=expires, 31 samesite='Lax', 32 secure=True, 33 ) 34 35 36class LoginView(GenericAPIView): 37 permission_classes = (AllowAny,) 38 serializer_class = CustomLoginSerializer 39 token_model = TokenModel 40 throttle_scope = 'dj_rest_auth' 41 42 @sensitive_post_parameters_m 43 def dispatch(self, *args, **kwargs): 44 return super(LoginView, self).dispatch(*args, **kwargs) 45 46 def process_login(self): 47 django_login(self.request, self.user) 48 49 def get_response_serializer(self): 50 if getattr(settings, 'REST_USE_JWT', False): 51 52 if getattr(settings, 'JWT_AUTH_RETURN_EXPIRATION', False): 53 response_serializer = JWTSerializerWithExpiration 54 else: 55 response_serializer = JWTSerializer 56 57 else: 58 response_serializer = TokenSerializer 59 return response_serializer 60 61 def login(self): 62 self.user = self.serializer.validated_data['user'] 63 64 if getattr(settings, 'REST_USE_JWT', False): 65 self.access_token, self.refresh_token = jwt_encode(self.user) 66 else: 67 self.token = create_token(self.token_model, self.user, 68 self.serializer) 69 70 if getattr(settings, 'REST_SESSION_LOGIN', True): 71 self.process_login() 72 73 def get_response(self): 74 serializer_class = self.get_response_serializer() 75 76 access_token_expiration = None 77 refresh_token_expiration = None 78 if getattr(settings, 'REST_USE_JWT', False): 79 from rest_framework_simplejwt.settings import \ 80 api_settings as jwt_settings 81 access_token_expiration = (timezone.now() + jwt_settings.ACCESS_TOKEN_LIFETIME) 82 refresh_token_expiration = (timezone.now() + jwt_settings.REFRESH_TOKEN_LIFETIME) 83 return_expiration_times = getattr(settings, 'JWT_AUTH_RETURN_EXPIRATION', False) 84 85 data = { 86 'user': self.user, 87 'access_token': self.access_token, 88 'refresh_token': self.refresh_token 89 } 90 91 if return_expiration_times: 92 data['access_token_expiration'] = access_token_expiration 93 data['refresh_token_expiration'] = refresh_token_expiration 94 95 serializer = serializer_class(instance=data, 96 context=self.get_serializer_context()) 97 else: 98 serializer = serializer_class(instance=self.token, 99 context=self.get_serializer_context()) 100 101 response = Response(serializer.data, status=status.HTTP_200_OK) 102 if getattr(settings, 'REST_USE_JWT', False): 103 from dj_rest_auth.jwt_auth import set_jwt_cookies 104 set_jwt_cookies(response, self.access_token, self.refresh_token) 105 set_userid_cookies(response) 106 107 return response 108 109 def post(self, request, *args, **kwargs): 110 self.request = request 111 self.serializer = self.get_serializer(data=self.request.data) 112 self.serializer.is_valid(raise_exception=True) 113 114 self.login() 115 return self.get_response()

Django

1# allauth設定 2ACCOUNT_USERNAME_REQUIRED = False 3ACCOUNT_AUTHENTICATION_METHOD = 'email' 4ACCOUNT_EMAIL_REQUIRED = True 5ACCOUNT_UNIQUE_EMAIL = True 6ACCOUNT_EMAIL_VERIFICATION = 'mandatory' 7ACCOUNT_LOGIN_ATTEMPTS_TIMEOUT = 600 8AUTHENTICATION_BACKENDS = [ 9 'allauth.account.auth_backends.AuthenticationBackend', 10 'django.contrib.auth.backends.ModelBackend', 11] 12 13# dj_rest_auth設定 14SITE_ID = 1 15REST_USE_JWT = True 16JWT_AUTH_COOKIE = 'access' 17JWT_AUTH_REFRESH_COOKIE = 'refresh' 18JWT_AUTH_HTTPONLY = True 19JWT_AUTH_SECURE = True 20REST_AUTH_SERIALIZERS = { 21 'USER_DETAILS_SERIALIZER': 'accounts.serializers.CustomUserSerializer' 22} 23 24# simple_jwt設定 25key = RSA.generate(2048) 26PRIVATE_KEY = key.export_key() 27PUBLIC_KEY = key.publickey().export_key() 28SIMPLE_JWT = { 29 'AUTH_HEADER_TYPES': ('JWT',), 30 'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5), 31 'REFRESH_TOKEN_LIFETIME': timedelta(hours=12), 32 'ROTATE_REFRESH_TOKENS': True, 33 'BLACKLIST_AFTER_ROTATION': True, 34 'ALGORITHM': 'RS256', 35 'SIGNING_KEY': PRIVATE_KEY, 36 'VERIFYING_KEY': PUBLIC_KEY, 37}

試したこと

フロントのアプリからログインをしてみました
実際にログイン自体は成功しています
問題はCookieがフロントにセットされないことだけです

補足情報(FW/ツールのバージョンなど)

OS: macOS 10.15.7
Next.js: 11.0.1
nginx: 1.21.1
Google Chrome

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

解決しました
どうやらsame siteがLaxになっていたのがダメだったようです

投稿2021/07/16 12:30

satoh23

総合スコア1

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問