SOPT:6回ワークショップ-restaPI、jwt
30499 ワード
追加材料-Neity 16 Velug
jwt
非接続性:サーバとサーバが接続を確立すると、サーバ応答が完了し、接続が終了する ステータスなし(ステータスなし)非接続性により、サーバがクライアント を認識できなくなる.
key-valueペアからなる小さなレコード情報ファイルで、コンピュータに格納されます.
1つの技術は、同じユーザの一連の需要を一定期間にわたって1つの状態と見なし、一致させることができる.
Cookieはクライアントにローカルに格納されているため、情報が変質したり交換されたりする可能性があります.
セッションはサーバ上でセッションストレージを使用するため、追加のストレージスペースが必要です.セッション・リポジトリに障害が発生した場合、検証に問題が発生します.
Json Web Token
クレームトークンに基づく認証方法.
クライアントのセッションステータスを保存するのではなく、トークンボディに必要な情報を保存して、クライアントが認証として使用できるようにします.
Header.Payload.Verify_Signature
Header:署名で使用されるアルゴリズムについて
Payload:クレームとして表示されるタグ情報を作成します.クライアントに関する情報が含まれます.
署名:トークンが変更されていないことを確認します.ヘッダーに指定されたアルゴリズムと秘密鍵には、ヘッダーとペイロードが含まれています. config/secretKey.js module/jwt.js userController.js URI:Uniform Resource Identifierインターネット上の唯一のアドレス URL:Uniform Resource Locatorネットワーク上のリソースの場所規則
uriはurlの概念 を含む
: REpresentational State Transfer API
リソースRESOURCE-URI
動作:-TTP METHOD
ひょうじほう
リソース名は動詞ではなく名詞です
APIリスト
API名 HTTP METHOD Content-Type 要求ヘッダ/ボディ 応答本体 Cross Origin Response Sharing
schema、host、portの3つは同じ-originであり、1つの違いはcross-origin である.
Web、サーバのサーバが異なる場合はエラー
jwt
authentication
APIリクエストが使用可能なユーザーであることを確認するプロセス
HTTP特性
HTTPでステータスを覚える方法
cookie
key-valueペアからなる小さなレコード情報ファイルで、コンピュータに格納されます.
セッション
1つの技術は、同じユーザの一連の需要を一定期間にわたって1つの状態と見なし、一致させることができる.
Cookieセッションの問題
Cookieはクライアントにローカルに格納されているため、情報が変質したり交換されたりする可能性があります.
セッションはサーバ上でセッションストレージを使用するため、追加のストレージスペースが必要です.セッション・リポジトリに障害が発生した場合、検証に問題が発生します.
JWT
Json Web Token
クレームトークンに基づく認証方法.
クライアントのセッションステータスを保存するのではなく、トークンボディに必要な情報を保存して、クライアントが認証として使用できるようにします.
JWT構成
Header.Payload.Verify_Signature
Header:署名で使用されるアルゴリズムについて
Payload:クレームとして表示されるタグ情報を作成します.クライアントに関する情報が含まれます.
署名:トークンが変更されていないことを確認します.ヘッダーに指定されたアルゴリズムと秘密鍵には、ヘッダーとペイロードが含まれています.
npm install jsonwebtoken
module.exports = {
secretKey: 'SecretKeySoptSeRvER',
options: {
algorithm: "HS256",
expiresIn: "1h",
issuer: "kgy",
},
refreshOptions: {
algorithm: "HS256",
expiresIn: "7d",
issuer: "kgy",
},
}
const jwt = require('jsonwebtoken');
const { secretKey, options, refreshOptions } = require('../config/secretKey');
const TOKEN_EXPIRED = -3;
const TOKEN_INVALID = -2;
module.exports = {
// jwt 생성
sign: async (user) => {
const payload = {
id: user.id,
name: user.userName
};
const result = {
accessToken: jwt.sign(payload, secretKey, options),
refreshToken: jwt.sign(payload, secretKey, refreshOptions),
};
return result;
},
// jwt 식별
verify: async (token) => {
let decoded;
try {
decoded = jwt.verify(token, secretKey);
} catch (err) {
if (err.message === 'jwt expired') {
console.log('expired token');
return TOKEN_EXPIRED;
} else if (err.message === 'invalid token') {
console.log('invalid token');
console.log(TOKEN_INVALID);
return TOKEN_INVALID;
} else {
console.log("invalid token");
return TOKEN_INVALID;
}
}
return decoded;
}
}
signin : async (req, res) => {
const { email, password } = req.body; // 1. req.body에서 데이터 가져오기
//2. request data 확인하기, email, password, userName data가 없다면 NullValue 반환
if (!email || !password) {
console.log('필요한 값이 없습니다!');
return res.status(statusCode.BAD_REQUEST).send(util.fail(statusCode.BAD_REQUEST, responseMessage.NULL_VALUE));
}
try{
//3. 존재하는 아이디인지 확인하기. 존재하지 않는 아이디면 NO USER 반환
const user = await User.findOne({
where : {
email : email
},
});
//4. 비밀번호 확인하기 - 로그인할 email의 salt를 DB에서 가져와서 사용자가 request로 보낸 password와 암호화를 한후 디비에 저장되어있는 password와 일치하면 true
// 일치하지 않으면 Miss Match password 반환
const {id, userName, salt, password : hashedPassword} = user;
const inputPassword = crypto.pbkdf2Sync(password, salt, 10000, 64, 'sha512').toString('base64');
if (inputPassword != hashedPassword) {
console.log('비밀번호가 일치하지 않습니다.');
return res.status(statusCode.BAD_REQUEST).send(util.fail(statusCode.OK, responseMessage.MISS_MATCH_PW));
}
const {accessToken, refreshToken} = await jwt.sign(user);
//5. status: 200 ,message: SIGN_IN_SUCCESS, data: id, email, userName 반환
return res.status(statusCode.OK).send(util.success(statusCode.OK, responseMessage.SIGN_IN_SUCCESS, {accessToken, refreshToken}));
} catch (error) {
console.error(error);
return res.status(statusCode.INTERNAL_SERVER_ERROR).send(util.fail(statusCode.INTERNAL_SERVER_ERROR, responseMessage.SIGN_IN_FAIL));
}
},
middle ware
const express = require('express');
const router = express.Router();
const ut = require('../modules/util');
const sc = require('../modules/statusCode');
const rm = require('../modules/responseMessage');
const jwt = require('../modules/jwt');
const TOKEN_EXPIRED = -3
const TOKEN_INVALID = -2
const authUtil = {
checkToken : async (req, res, next) => {
const token = req.headers.jwt;
if (!token) {
return res.json(ut.fail(sc.BAD_REQUEST, rm.EMPTY_TOKEN));
}
const user = await jwt.verify(token);
console.log('hello', user);
if (user === TOKEN_EXPIRED) {
return res.status(sc.UNAUTHORIZED).send(ut.fail(sc.UNAUTHORIZED, rm.EXPIRED_TOKEN));
}
if (user === TOKEN_INVALID) {
return res.status(sc.UNAUTHORIZED).send(ut.fail(sc.UNAUTHORIZED, rm.INVALID_TOKEN));
}
if (user.id === undefined) {
return res.status(sc.UNAUTHORIZED).send(ut.fail(sc.UNAUTHORIZED, rm.INVALID_TOKEN));
}
req.decoded = user;
next();
},
}
module.exports = authUtil;
REST API
uriはurlの概念
REST API
: REpresentational State Transfer API
構成
リソースRESOURCE-URI
動作:-TTP METHOD
ひょうじほう
REST API設計ガイドライン
1.URIは情報のリソースを表す必要があります。
リソース名は動詞ではなく名詞です
GET/members/show
xGET/hahaha
xGET/members
o2.資源の行為はHTTP方法(GET、POST、PUT、DELETE)を採用する
REST API注意事項
1./(スラッシュ)階層関係を表す
2.URIの最後の文字にスラッシュは含まれません。
3-(ハイフン)URIによる毒性向上
4.(下線)URIに使用しない
5.URIパスの小文字有効
6.ファイル拡張子はURIに含まれません。
GET/sopt/server.png
xGET/sopt/server/png
o7.コレクションは複数、装飾は単数
document는 하나의 객체(문서), collection은 그 객체들의 집합
http://sopt.org/parts/server/users/2
APIリスト
API: Application Programming Interface
クライアントを使用してサーバ上に作成されたAPIのユーザーズガイド.
APIインベントリコンポーネント
CORS
schema、host、portの3つは同じ-originであり、1つの違いはcross-origin
Web、サーバのサーバが異なる場合はエラー
npm install cors
-app.jsでconst cors = require('cors');
app.use(cors());
Reference
この問題について(SOPT:6回ワークショップ-restaPI、jwt), 我々は、より多くの情報をここで見つけました https://velog.io/@jujube0/SOPT-6차-세미나テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol