JWTのデコードしたデータについて
解決したいこと
・Node.js
・MongoDB
・Typescript
・mongooseライブラリ
・Expressフレームワーク
・jsonwebtoken
を使用し、ログイン機能を実装しています。
解決したいことといたしましては、
- クライアントから受け取ったJWTトークン(エンコードしたもの)を
.verify
でデコードしたJwtTokenDecode
を、なぜ以下の書き方でMongoDBから一致する_idのデータを引き出せるのかfindById(JwtTokenDecode)
-
findById(JwtTokenDecode._id)
だと_id
に赤線が入りエラーが吐かれ処理が落ちるのか
エラーの内容:プロパティ '_id' は型 'string | JwtPayload' に存在しません。
プロパティ '_id' は型 'string' に存在しません。ts(2339)
該当するソースコード
import { Request, Response, NextFunction } from 'express';
import JWT from 'jsonwebtoken';
import { User } from '../models/user';
// クライアントから渡されたJWTが正常か
export const jwtTokenDecode = (req: Request) => {
const bearerHeader = req.headers['authorization'];
if (bearerHeader) {
const bearer = bearerHeader.split(' ')[1];
try {
// .verifyでデコードする
const jwtDecodedToken = JWT.verify(
bearer,
process.env.JWT_TOKEN_SECRET_KEY ?? ''
);
return jwtDecodedToken;
} catch (error) {
console.log('JWTTokenError', error);
return false;
}
}
};
// JWT認証を検証
export const verifyToken = async (
req: Request,
res: Response,
) => {
const JwtTokenDecoded = jwtTokenDecode(req);
if (JwtTokenDecoded) {
// JwtTokenDecodedの型が、 string | JWT.JwtPayload
// MongoDBから_idが一致するユーザーを取得
const user = await User.findById(JwtTokenDecoded);
if (!user) {
return res.status(401).json('権限がありません');
} else {
req.body.user = user;
}
} else {
return res.status(401).json();
}
};
処理としては正常に動いているのですが、console.logでJwtTokenDecoded
の中身を見たところ、
{
_id: 'デコードされたid(mongodbに保存されている_idと一致)',
iat: 1670567743,
exp: 1670654143
}
が格納、typeof をしたところ object となっていました。
この場合でいくと、JwtTokenDecoded.id
とする必要があると思ったのですが、この形だとエラーを吐かれます。
しかし、JwtTokenDecoded
をホバーすると型は、string | JWT.JwtPayload
になっていました。
型がstring | JWT.JwtPayload
だから、findById(JwtTokenDecode)
の書き方で、MongoDBからidが一致するデータを取得できると納得はしたのですが、
実際に中身を見るとobjectなのでfindById(JwtTokenDecode._id)
しなければいけないのでは?と疑問を感じています。
なぜfindById(JwtTokenDecode._id)
ではエラーを吐かれ、findById(JwtTokenDecode)
でデータの取得ができるのでしょうか?
拙い文で申し訳ないのですが、ご教示いただけると幸いです。
自分で試したこと
interface MongoUserId {
_id: string;
}
//省略...
// .verifyでデコードする
const jwtDecodedToken = JWT.verify(
bearer,
process.env.JWT_TOKEN_SECRET_KEY ?? ''
) as MongoUserId;
と、型アサーションするとfindById(JwtTokenDecode._id)
がエラーにならず正常に動作します。