JWTによるサーバ認証と認証
15005 ワード
質問する
少し前にプロジェクトを開発・配置した.
テストを準備して、サーバがさまざまな状況で正常に動作していることを確認しています.
変なところが見えてきました.
「アドレス」ウィンドウに「サーバー・アドレス/リソース/識別子」と入力すれば、誰でも使用できます.
返事をもらう.
ソリューション
この問題を解決するために、解決策を探しました.だいたい2種類あります.
session
1つ目はセッションによるユーザ認証です.
この方法の問題は、サーバがステータスを維持しなければならないことです.
私のプロジェクトはnodejsで実行されています.
このプロジェクトでは,状態保持を実現する方法は2つある.
プロセス間通信
NodejsはCPUコアを使用します.Nodeとして実行されるサーバは、負荷が増加すると、複数のカーネル上でプロセスを実行する必要があります.したがって,状態保持を実現するためにはプロセス間で通信が必要であり,この方法は状況を複雑にする.
キャッシュ
プロセスの先頭にスローを保存します.これにより、複数のプロセスは、キャッシュ内でセッション情報を迅速に維持することができる.しかし、私のプロジェクトはclientがステータス管理を行うので、サーバのステータスを維持する必要はないと思います.
jwt
2つ目はjson web tokenを使用する方法です.
このメソッドは、認証をサーバに要求したユーザーにトークンを発行します.ユーザーは次のことができます.
リクエストから、コインを含むリクエスト方式.サーバはユーザ状態を維持する必要はなく,トークンの有効性を判断するだけでよい.
もちろん、コインは奪われる可能性があります.
対応方式はaccessTokenとrefreshTokenである.
accessTokenは、有効期間を短縮し、期限が切れたらrefreshTokenを使用してaccessTokenを再発行する方法です.
これを行うと、accessTokenを奪ってもあまり使用されません.refreshTokenを奪った場合、データベースから削除してアクセスをブロックできます.
イニシアチブ
実施前にシナリオを作成した.
資格認定
登録またはログインお客様は、会員登録または登録を要求します. サーバは、accessToken、refreshTokenを送信して応答する.このとき、refreshTokenはデータベースに格納されます. clientは、応答するaccessToken、refreshTokenをローカルに保存する. 承認
accessTokenが期限切れでない場合 clientはaccessTokenをヘッダ要求に入れる. サーバはaccessTokenをチェックして応答します. accessTokenは期限切れで、refreshTokenは期限切れではありません. clientはaccessTokenをヘッダ要求に入れる. サーバはaccessTokenの確認後に期限切れになるため、403 Forbiddenに応答する. client 403が受信された場合、refreshTokenはタイトルに要求される. サーバは、refreshTokenをチェックし、新しいリリースの応答にaccessTokenを含めます. clientは応答のaccessTokenを格納する. accessTokenもrefreshTokenも期限切れ clientはaccessTokenをヘッダ要求に入れる. サーバはaccessTokenの確認後に期限切れになるため、403 Forbiddenに応答する. client 403が受信された場合、refreshTokenはタイトルに要求される. サーバは、refreshTokenの確認後に期限が切れたため、403 Forbiddenに応答する. clientローカルトークンをキャンセルして終了します. tokenが存在しないか無効ですサーバ応答401. インプリメンテーション
jwtを用いた認証と認可を実現するには,2種類が必要である.
トークンリリース関数
accessTokenとrefreshTokenの関数を発行します.
その後、すべてのリクエストに対して確認トークンを使用するミドルウェア.
既存のすべてのリクエストに対する応答は解決されましたが、まだ問題があります.ログインリクエストまたは会員加入リクエストは、依然として応答します. accessTokenが盗まれた場合、応答は有効時間内に行われる. コインが盗まれたかどうか分かりません.
少し前にプロジェクトを開発・配置した.
テストを準備して、サーバがさまざまな状況で正常に動作していることを確認しています.
変なところが見えてきました.
「アドレス」ウィンドウに「サーバー・アドレス/リソース/識別子」と入力すれば、誰でも使用できます.
返事をもらう.
ソリューション
この問題を解決するために、解決策を探しました.だいたい2種類あります.
session
1つ目はセッションによるユーザ認証です.
この方法の問題は、サーバがステータスを維持しなければならないことです.
私のプロジェクトはnodejsで実行されています.
このプロジェクトでは,状態保持を実現する方法は2つある.
プロセス間通信
NodejsはCPUコアを使用します.Nodeとして実行されるサーバは、負荷が増加すると、複数のカーネル上でプロセスを実行する必要があります.したがって,状態保持を実現するためにはプロセス間で通信が必要であり,この方法は状況を複雑にする.
キャッシュ
プロセスの先頭にスローを保存します.これにより、複数のプロセスは、キャッシュ内でセッション情報を迅速に維持することができる.しかし、私のプロジェクトはclientがステータス管理を行うので、サーバのステータスを維持する必要はないと思います.
2つ目はjson web tokenを使用する方法です.
このメソッドは、認証をサーバに要求したユーザーにトークンを発行します.ユーザーは次のことができます.
リクエストから、コインを含むリクエスト方式.サーバはユーザ状態を維持する必要はなく,トークンの有効性を判断するだけでよい.
もちろん、コインは奪われる可能性があります.
対応方式はaccessTokenとrefreshTokenである.
accessTokenは、有効期間を短縮し、期限が切れたらrefreshTokenを使用してaccessTokenを再発行する方法です.
これを行うと、accessTokenを奪ってもあまり使用されません.refreshTokenを奪った場合、データベースから削除してアクセスをブロックできます.
イニシアチブ
実施前にシナリオを作成した.
資格認定
登録またはログイン
accessTokenが期限切れでない場合
jwtを用いた認証と認可を実現するには,2種類が必要である.
トークンリリース関数
accessTokenとrefreshTokenの関数を発行します.
// 사용자의 id, access토큰인지 refresh토큰인지, 만료시간을 받아서 토큰을 발행한다.
const jwt = require("jsonwebtoken");
const issueAtoken = (id, which, expiresIn) => {
const token = jwt.sign({ id, which }, process.env.JWTSECRET, { expiresIn });
return token;
};
会員登録または登録時にコインを発行します. ...
const accessToken = issueAtoken(userId, "access", "60m");
const refreshToken = issueAtoken(userId, "refresh", "1800m");
...
res.json({
code: 200,
accessToken,
refreshToken,
...
});
トークン確認ミドルウェアその後、すべてのリクエストに対して確認トークンを使用するミドルウェア.
const jwt = require("jsonwebtoken");
const verifyToken = async (req, res, next) => {
try {
// 토큰이 유효한지 확인한다. 유효하지 않다면 error를 던진다.
const decoded = jwt.verify(
req.headers.authorization,
process.env.JWTSECRET
);
// refreshToken이 온 경우 데이터베이스의 refreshToken과 비교한다.
if (decoded.which === "refresh") {
const { QUERY, EQ } = POOL;
const row = await QUERY`SELECT refreshToken FROM RefreshTokens WHERE ${EQ(
{
userId: decoded.id,
}
)}`;
// refreshToken이 탈취당한 경우 데이터베이스의 토큰을 삭제하여 방어할 수 있다.
if (row[0].refreshToken !== req.headers.authorization) {
return res.status(401).json({
code: 401,
message: "JsonWebTokenError",
});
}
req.newAccessToken = issueAtoken(decoded.id, "access", "60m");
}
return next();
} catch (error) {
console.log(error);
// 토큰이 만료된 경우 403 Forbidden
if (error.name === "TokenExpiredError") {
res.json({
code: 403,
message: "TokenExpiredError",
});
return res.end();
}
// 토큰이 유효하지 않는 경우 401 Unauthorized
if (error.name === "JsonWebTokenError") {
res.status(401).json({
code: 401,
message: "JsonWebTokenError",
});
return res.end();
}
res.status(500);
return res.end();
}
};
残念な点既存のすべてのリクエストに対する応答は解決されましたが、まだ問題があります.
Reference
この問題について(JWTによるサーバ認証と認証), 我々は、より多くの情報をここで見つけました https://velog.io/@imtaebari/JWT로-서버-인증-인가-구현하기テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol