0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

SPAでcookie付与

Last updated at Posted at 2023-07-14

背景

drf+reactでローカルで開発中。

ログインでaccessトークンを発行していたのだが、cookieにsetされない。

特にエラーも出ない。しかしクッキーは保存されない。

クッキーについて調べてみた。

調査

アクセストークンを発行するのに以下のライブラリ使用。

dj-rest-auth,simpleJWT

調査には大きく3つ。

  • Cookieの属性
  • CSRF
  • CORS

まずはCookieの属性。

その設定が以下。

REST_AUTH = {
    'USE_JWT': True,
    'JWT_AUTH_COOKIE': 'my-app-auth',
    'JWT_AUTH_HTTPONLY':True, 
    'JWT_AUTH_COOKIE_USE_CSRF' : True,
    # 'JWT_AUTH_SAMESITE':'None',
    # 'JWT_AUTH_SECURE':True
}
from datetime import timedelta
# JWT setting
SIMPLE_JWT = {
    "ACCESS_TOKEN_LIFETIME": timedelta(hours=1),
}

よく分からず設定していたので調査。

設定項目で必要そうなcookieの属性とやらを調べた結果。

Secure属性

https通信でしかcookieの送信は許さない。Secureに通信するための属性。

httpOnly属性

JavaScript の document.cookie では値を取得することができません。また document.cookie に対して HttpOnly 属性がついた値を Cookie に書き込むこともできません。xss攻撃に有効。

SameSite属性

A というサイトから B というサイトへリンクなどを経由して遷移するときに、ブラウザに保存されている B の Cookie を送信するかどうかのコントロールをおこなうための属性です。

ドメインの異なるサイト間でcookieを送信するのかってこと。

None、Lax、Strictの3つを設定可能。

NoneはなんでもOK。

Laxはgetだけ許す。

Strictは禁止。

NoneにしておけばOKだが、Secure属性をtrueにしとかないといけないらしい。

正味、localで開発する場合オリジンは異なるがドメインは異ならないのでNoneにする必要はないが、、、


次にCSRFトークン。

何となくの理解で、csrf攻撃を防ぐためのトークンという認識。

その設定が以下。

CSRF_TRUSTED_ORIGINS =["http://localhost:3000"]
# CSRF_COOKIE_SAMESITE ='None'
# CSRF_COOKIE_SECURE =True

csrfトークンに関してもsamesiteとsecureが設定可能。


次にCORS。

これは以前調査したので大体は理解している。

cors-headersライブラリ使用。

corsの設定。

CORS_ALLOWED_ORIGINS = [
    "http://localhost:3000",
]
CORS_ALLOW_METHODS = (
    "DELETE",
    "GET",
    "OPTIONS",
    "PATCH",
    "POST",
    "PUT",
)
CORS_ALLOW_HEADERS = (
    "accept",
    "authorization",
    "content-type",
    "user-agent",
    "x-csrftoken",
    "x-requested-with",
    "access-control-allow-origin",
    "access-control-allow-credentials",
)

上から

リクエストを許可するオリジン、メソッド、header項目。

axios設定。

export const axiosInstance = axios.create({
  baseURL: API_URL,
  headers: {
    "Access-Control-Allow-Origin": "http://localhost:3000",
    "Access-Control-Allow-Credentials": "true",
  },
});

~~~~~~~~
const response = await axiosInstance.post(
        "/auth/login/",
        {
          email,
          password,
        },
        { withCredentials: true }
      );

リクエストにクッキーを付与するためにwithCredentialsを。

解決策

localhostで行う場合は、samesite,secure設定はデフォルトでいい。(ライブラリの違いがあるためデフォルト値を確かめる。)

私が誤っていたのは2点。

  • CORS_ALLOW_HEADERSに"access-control-allow-credentials"を設定したら、リクエストにクッキーを付与する許可になると思っていた。(access-control-allow-originがそうだったから、、同じようにすればいいと、、、、、)
  • axiosの設定で"Access-Control-Allow-Credentials": "true"は必要ない。

CORSでCookieのやり取りをした場合、Access-Control-Allow-Credentialsをtrueにしないといけない。

Access-Control-Allow-Credetials=trueってのを設定するためにはバックエンドは

CORS_ALLOW_CREDENTIALS

という値を設定する必要がある。(drfだったら)

またフロントもaxiosのheadersに"Access-Control-Allow-Credentials": "true"を書いても意味ない。

withCredentials:trueでCookieなどの資格情報を使用することができる。

gitのissueにもあった。
https://github.com/iMerica/dj-rest-auth/issues/192

express使ったときは

にAccess-Control-Allow-Credetials=trueを設定する方法が載っていた。

httpsでローカルでやりたい人はコンテナを使えば楽。
steveltn/https-portalイメージを使用してみたがとても簡単にhttps設定ができた。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?