JWT周りについて理解するために読んだサイト
- ユーザー情報を埋め込んでいるので、ユーザのログイン情報をRedisやMySQLに保存しなくていい。パフォーマンスがいい。
- ブラウザとネイティブで同じ仕組みが使える。
読んだサイト
- Yahoo: https://techblog.yahoo.co.jp/advent-calendar-2017/jwt/
- 一番分かりやすい OAuth の説明: https://qiita.com/TakahikoKawasaki/items/e37caf50776e00e733be
- リフレッシュトークン:https://medium.com/monstar-lab-bangladesh-engineering/jwt-auth-in-go-part-2-refresh-tokens-d334777ca8a0
- https://kamichidu.github.io/post/2017/01/24-about-json-web-token/
どこに保存するか
まとめ: https://mannharleen.github.io/2020-03-19-handling-jwt-securely-part-1/
Persisting JWT token in localstorage (prone to XSS) < Persisting JWT token in an HttpOnly cookie (prone to CSRF, a little bit better for XSS) < Persisting refresh token in an HttpOnly cookie (safe from CSRF, a little bit better for XSS).
from https://hasura.io/blog/best-practices-of-using-jwt-with-graphql/#login_usage
LocalStorage
-
そもそも使うなという話 https://www.rdegges.com/2018/please-stop-using-local-storage/
-
この記事だとSessionStorage: https://medium.com/@rajaraodv/securing-react-redux-apps-with-jwt-tokens-fcfe81356ea0
-localStrogeに保存せずに...という話。
Do not store the token in localStorage, the token can be compromised using xss attack. I think the best solution will be to provide both access token and refresh token to the client on login action. save the access token in memory (e.g redux state) and the refresh token should be created on the server with httpOnly flag (and also secure flag if possible). The access token should be set to expire every 2-3 minutes. In order to make sure that the user will not have to enter his credentials every 2-3 minutes I have an interval which calls the /refreshToken endpoint before the current token expires (silent refresh token).
Golangでの利用
-
jwt-go
-
リフレッシュトークン
-
サンプルの実装だが動かない気がする: https://github.com/thealmarques/go-graphql-gqlgen-jwt
Frontendでの扱い
- Next.jsでCookieに保存: https://maxschmitt.me/posts/next-js-http-only-cookie-auth-tokens/s
Debugger
メモ
ログイン情報を保持する方法としては、Session BasedとToken Basedがある。
Cookieに保存する場合、HttpOnly属性を利用するとJavaScriptから利用できなくなる。: https://stackoverflow.com/questions/14691654/set-a-cookie-to-httponly-via-javascript
アクセストークンを使う場合リフレッシュトークンを使ってログイン状態を維持するらしい。
- アプリでID/Passを保存せずにセキュアにやりとりするための仕組みとしてアクセストークンという概念がある。
- アクセストークンの有効期限は短いのでリフレッシュトークンという有効期限の長いトークンを合わせて発行し、リフレッシュトークンを使う事で新しいアクセストークンを得られる。 この仕組みでログイン維持の振る舞いが出来る。
- リフレッシュトークンはGoogleだと6ヶ月の生存期間を持つ
- トークンはkeychainに保存するのが良いっぽい
- 古いリフレッシュトークンはクライアントで破棄し、毎回新しいものと置換する
from https://qiita.com/yosshi4486/items/7ec5fdd53577c8663603
でWebでは、具体的にリフレッシュトークンをどこに保存してどういうタイミングで使うかは
- The user logs in with a login API call.
- Server generates JWT Token and refresh_token
- Server sets a HttpOnly cookie with refresh_token. jwt_token and jwt_token_expiry are returned back to the client as a JSON payload.
- The jwt_token is stored in memory.
- A countdown to a future silent refresh is started based on jwt_token_expiry
from https://hasura.io/blog/best-practices-of-using-jwt-with-graphql/#login_usage
Discussion