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

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

新規登録して質問してみよう
ただいま回答率
85.50%
JWT(JSON Web Token)

JWT(JSON Web Token)とは、JSONをベースとしたアクセストークンの仕様。電子署名付きのURL safeなJSONのことを指します。電子署名が付いているため、改ざんをチェックできる点がメリットです。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Q&A

解決済

1回答

1338閲覧

passport-jwt の利用時に、有効なアクセストークンを持っていなくてもとりあえず通したい

mochi.monaka

総合スコア26

JWT(JSON Web Token)

JWT(JSON Web Token)とは、JSONをベースとしたアクセストークンの仕様。電子署名付きのURL safeなJSONのことを指します。電子署名が付いているため、改ざんをチェックできる点がメリットです。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

0グッド

0クリップ

投稿2021/06/07 15:26

編集2021/06/07 15:38

passport-jwt を使っています。
正確には、Nestjs にて @nestjs/passport と併せて使っています。

ユーザ登録〜ログインと、ログイン時に発行する JWT アクセストークンを使ったユーザ認証の実装をして、
これは期待どおり動作しています。


しかし要件として、
リクエストがアクセストークンを持っていなくても弾かずに、未ログインユーザとしてアクセスを通したいと思います。

ユースケースとしてはたとえば、
ログインしていなくても「商品」データにアクセスできるが、ログインした上で「商品」データを見たら自分が過去に購入したかどうかまで取れる、
または、ログインしていなくても「商品」に付いたいいね数を見れるが、ログインした上でなら自分がいいね済かどうかまで取れる、など。

ユーザ認証でアクセスを弾きたいわけでなく、ユーザIDを「取れるなら取りたい」くらいの緩い認証をしたい場面はよくあると思います。


リクエスト時の流れを追ってみましたが、
passport-jwt を使うとどうやら、リクエストが「JWT アクセストークンとして有効な文字列」をまず持っている状態でなければ、実際の認証(DB から User を抽出するような実際的な部分)に到達する以前に、問答無用で弾く仕組みのように思いました。
アクセストークンを持っていなかったり不正なら、未ログインユーザとしてアクセスを続行したいのですが、そういう工夫をするフックを書こうにも、まず到達自体しません。

「緩い認証」はどのように実現できるでしょうか?
今回 passport-jwt を初めて使っています。初歩的なアドバイスでも助かります。

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

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

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

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

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

guest

回答1

0

自己解決

調査の限りでは無理そうでしたので、
コントローラに JWT ガードを仕掛けず無条件で一旦受け入れて、
その後のコントローラ内で、自分でリクエストヘッダからアクセストークンのパースや有効期限バリデーション等を実装しました。
さらに nestjs 向けということでカスタムデコレータ化しました。


解決というか、自分で全部書いているため当然自由に処理できますが、
ユースケースは特殊でない、むしろよくあることなので、本当に方法が用意されていないのかなとはまだ思っています。
認証ロジックを2重に実装することになり、よくない状態です。

ステータスは解決にしますが、ご存知のかたご指摘いただけると幸いです。

投稿2021/06/08 14:07

mochi.monaka

総合スコア26

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

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

mochi.monaka

2021/06/11 21:06

その後、 nestjs のやり方でいえば、 `AuthGuard('jwt')` クラスを継承したガードを実装することで解決できました! オーバーライドした `handleRequest()` には、 JWT 認証が成功していれば `User` エンティティが渡ってきます。失敗なら `undefined` が渡ってきます。 どちらの状況であっても `handleRequest()` 内では何もせずに( JWT 認証失敗の例外を投げたりせずに)単にその `User` や `undefined` を `return` だけします。 `return` された値が `Request` オブジェクトに `user` として生えるので、コントローラ内で自由に参照できます。 認証ロジック実装の重複を脱することができました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問