20220106
--バックエンド
CMD> nodemon --inspect ./bin/www
--フロントエンド
CMD> npm run serve
//照会:thisを待つ.axios.get(url, {headers:headers});
//追加:thisを待ちます.axios.post(url, body, {headers:headers});
//修正:これを待つ.axios.put(url, body, {headers:headers});
//削除:thisを待ちます.axios.delete(url, {headers:headers, data:{}});
//ファイル名:config/auth.js
//トークンの作成、抽出、検証が必要
const jwt = require('jsonwebtoken');
const self = module.exports = {
securityKey : 'fjifej$%e_ijfj39890uu94343',
options : {
アルゴリズム:“HS 256”,//トークン生成hashアルゴリズム
expiressin:9 h,//トークン有効期限ex)9時間
発行者:「corp 01」//トークン発行者
},
//ファイル名:member.js
var express = require('express');
var router = express.Router();
//モンゴルDBバインド
//CMD> npm i mongodb --save
const db = require('mongodb').MongoClient;
const DBURL = require('../config/db').mongodbURL;
const DBNAME = require('../config/db').mongodbDB;
//ログイン時にトークンを発行する
//CMD> npm i jsonwebtoken --save
const jwt = require('jsonwebtoken');
const jwtKey = require('../config/auth').securityKey;
const jwtOptions = require('../config/auth').options;
const checkToken = require('../config/auth').checkToken;
//会員入力、ログイン時のパスワードhash
const crypto = require('crypto');
//会員情報の伝達http://localhost:3000/member/selectone
router.get('/selectone', checkToken, async function(req, res, next) {
try {
//身分:req.body.userid(auth.jsに手動で転送!)
const dbConn = await db.connect(DBURL);
const coll = dbConn.db(DBNAME).collection("member");
//会員情報修正:http://localhost:3000/member/mypage?menu=1
//パスワード変更:http://localhost:3000/member/mypage?menu=2
//会員脱退:http://localhost:3000/member/mypage?menu=3
router.put('/mypage', checkToken, async function(req, res, next) {
try {
//console.log( req.query.menu ); // 結果について
//console.log( typeof req.query.menu );//タイプ情報
//ログイン:http://localhost:3000/member/select
//パスワード情報があるので、post
router.post('/select', async function(req, res, next) {
try {
//会員登録時に使用しなければならない暗号化方式hash
登録比較は//DBから行えます.
const hash = crypto.createHmac('sha256', req.body.uid)
.update(req.body.upw).digest('hex');
//会員入力:http://localhost:3000/member/insert
router.post('/insert', async function(req, res, next) {
try{
console.log(req.body);
//hash(salt)はabc->io 3 rj 987 io 23873987437839 ufj 3983 r
const hash = crypto.createHmac('sha256', req.body.uid)
.update(req.body.upw).digest('hex');
const obj = {
_id : req.body.uid,
userpw : hash,
userage : Number(req.body.uage),
userbirth : req.body.ubirth,
useremail : req.body.uemail,
usercheck : req.body.ucheck,
usergender : Number(req.body.ugender)
};
console.log(obj);
//重複認証:http://localhost:3000/member/idcheck?uid=aa
router.get('/idcheck', async function(req, res, next) {
try {
const userid = req.query.uid;
module.exports = router;
============================================
//ファイル名:Mypage.vue
CMD> nodemon --inspect ./bin/www
--フロントエンド
CMD> npm run serve
//照会:thisを待つ.axios.get(url, {headers:headers});
//追加:thisを待ちます.axios.post(url, body, {headers:headers});
//修正:これを待つ.axios.put(url, body, {headers:headers});
//削除:thisを待ちます.axios.delete(url, {headers:headers, data:{}});
//ファイル名:config/auth.js
//トークンの作成、抽出、検証が必要
const jwt = require('jsonwebtoken');
const self = module.exports = {
securityKey : 'fjifej$%e_ijfj39890uu94343',
options : {
アルゴリズム:“HS 256”,//トークン生成hashアルゴリズム
expiressin:9 h,//トークン有効期限ex)9時間
発行者:「corp 01」//トークン発行者
},
// 토큰이 전달되면 토큰의 유효성을 검증함.
checkToken : async(req, res, next) => {
try {
const token = req.headers.token;
// 1. 토큰이 있느냐?
if(!token){
return res.send({status:-1, result:'토큰이 없음.'});
}
// 2. 토큰 decode 추출(토큰과 암호키)
const user = jwt.verify(token, self.securityKey);
if(typeof user.uid === 'undefined'){
return res.send({status:-1, result:'유효하지 않는 토큰'});
}
console.log('토큰에서 추출한 아이디 => ', user.uid);
// 수동으로 body에 포함(아이디, 이메일, 나이)
req.body.userid = user.uid;
// 위쪽에서 토큰에 대한 유효성을 모두 pass할경우 다음으로 넘김
// member.js가 호출 (이메일, 나이)
next();
}
catch(err){
console.error(err);
if(err.message === 'invalid signature'){
return res.send({status:-1, result : "인증실패"});
}
else if(err.message === 'jwt expired') {
return res.send({status:-1, result : "시간만료"});
}
else if(err.message === 'invalid token'){
return res.send({status:-1, result : "유효하지 않는 토큰"});
}
return res.send({status:-1, result : err});
}
}
}//ファイル名:member.js
var express = require('express');
var router = express.Router();
//モンゴルDBバインド
//CMD> npm i mongodb --save
const db = require('mongodb').MongoClient;
const DBURL = require('../config/db').mongodbURL;
const DBNAME = require('../config/db').mongodbDB;
//ログイン時にトークンを発行する
//CMD> npm i jsonwebtoken --save
const jwt = require('jsonwebtoken');
const jwtKey = require('../config/auth').securityKey;
const jwtOptions = require('../config/auth').options;
const checkToken = require('../config/auth').checkToken;
//会員入力、ログイン時のパスワードhash
const crypto = require('crypto');
//会員情報の伝達http://localhost:3000/member/selectone
router.get('/selectone', checkToken, async function(req, res, next) {
try {
//身分:req.body.userid(auth.jsに手動で転送!)
const dbConn = await db.connect(DBURL);
const coll = dbConn.db(DBNAME).collection("member");
const result = await coll.findOne(
{ _id : req.body.userid }, // 조건
{ projection : { userpw:0, _id:0 } } // 필요없는 항목제거
);
return res.send({status:200, result:result});
}
catch(err) {
console.error(err);
return res.send({status:-1, result : err});
}
});//会員情報修正:http://localhost:3000/member/mypage?menu=1
//パスワード変更:http://localhost:3000/member/mypage?menu=2
//会員脱退:http://localhost:3000/member/mypage?menu=3
router.put('/mypage', checkToken, async function(req, res, next) {
try {
//console.log( req.query.menu ); // 結果について
//console.log( typeof req.query.menu );//タイプ情報
const menu = Number(req.query.menu);
const dbConn = await db.connect(DBURL);
const coll = dbConn.db(DBNAME).collection("member");
if (menu === 1) {
const result = await coll.updateOne(
{ _id : req.body.userid }, //조건
{ $set : {
userage: req.body.userage,
useremail:req.body.useremail
}
},// 변경내용
);
console.log(result); // 실패 or 성공
if(result.modifiedCount === 1){
return res.send({stauts:200});
}
return res.send({status: 0});
}
else if(menu === 2) {
// req.body.userid 아이디(변경X)
// req.body.userpw 현재암호
// req.body.userpw1 바꿀암호
const hash = crypto.createHmac('sha256', req.body.userid)
.update(req.body.userpw).digest('hex');
const hash1 = crypto.createHmac('sha256', req.body.userid)
.update(req.body.userpw1).digest('hex');
const result = await coll.updateOne(
//조건 아이디와 현재암호가 일치하는 조건
{ _id : req.body.userid, userpw:hash },
//변경할 내용 바꿀암호
{ $set : {userpw: hash1 }}
);
console.log(result); // 실패 or 성공
if(result.modifiedCount === 1){
return res.send({stauts:200});
}
return res.send({status: 0});
}
else if(menu === 3) {
// req.body.userid 아이디
// req.body.userpw 암호
const hash = crypto.createHmac('sha256', req.body.userid)
.update(req.body.userpw).digest('hex');
const result = await coll.deleteOne(
{ _id:req.body.userid, userpw:hash } //삭제 조건 : 아이디, 암호일치할경우
);
console.log(result);
// 삭제보다는 필요시에 중요정보를 updateOne.
if(result.deletedCount === 1) {
return res.send({status:200});
}
return res.send({status:0});
}
return res.send({status:-1, result:"메뉴정보 없음"});
}
catch(err) {
console.error(err);
return res.send({status:-1, result : err});
}
});//ログイン:http://localhost:3000/member/select
//パスワード情報があるので、post
router.post('/select', async function(req, res, next) {
try {
//会員登録時に使用しなければならない暗号化方式hash
登録比較は//DBから行えます.
const hash = crypto.createHmac('sha256', req.body.uid)
.update(req.body.upw).digest('hex');
const obj = {
userid : req.body.uid,
userpw : hash
};
console.log(obj);
const dbConn = await db.connect(DBURL);
const coll = dbConn.db(DBNAME).collection("member");
// const query = { $and : [{_id:obj.userid}, {userpw:obj.userpw}] };
const query = { _id:obj.userid, userpw:obj.userpw };
const result = await coll.findOne(query);
console.log(result); // 실패 or 성공
if(result !== null){ // DB에 일치하는 경우
const token = {
token : jwt.sign(
{ uid : result._id }, // 토큰에 포함할 내용들...
jwtKey, // 토큰생성 키
jwtOptions // 옵션
),
refreshToken : null, // null
}
return res.send({status:200, result : token});
}
// 일치하지 않을 경우
return res.send({status:0});
}
catch(err) {
console.error(err);
return res.send({status:-1, result : err});
}
});//会員入力:http://localhost:3000/member/insert
router.post('/insert', async function(req, res, next) {
try{
console.log(req.body);
//hash(salt)はabc->io 3 rj 987 io 23873987437839 ufj 3983 r
const hash = crypto.createHmac('sha256', req.body.uid)
.update(req.body.upw).digest('hex');
const obj = {
_id : req.body.uid,
userpw : hash,
userage : Number(req.body.uage),
userbirth : req.body.ubirth,
useremail : req.body.uemail,
usercheck : req.body.ucheck,
usergender : Number(req.body.ugender)
};
console.log(obj);
const dbConn = await db.connect(DBURL);
const coll = dbConn.db(DBNAME).collection("member");
const result = await coll.insertOne(obj); //{ }
console.log(result); // 성공 or 실패
if( result.insertedId === obj._id ) {
return res.send({status:200});
}
return res.send({status:0});
}
catch(err) {
console.error(err);
return res.send({status:-1, result : err});
}
});//重複認証:http://localhost:3000/member/idcheck?uid=aa
router.get('/idcheck', async function(req, res, next) {
try {
const userid = req.query.uid;
const dbConn = await db.connect(DBURL);
const coll = dbConn.db(DBNAME).collection("member");
const query = { _id : userid };
const result = await coll.countDocuments(query);
console.log(result); //{ }
return res.send({status:200, result:result});
}
catch(err) {
console.error(err);
return res.send({status:-1, result : err});
}
});module.exports = router;
============================================
//ファイル名:Mypage.vue
<div>
<h4>마이페이지</h4>
<el-card shadow="always">
<el-tabs tab-position="left" style="height: 200px">
<el-tab-pane label="정보수정">
<menu-1></menu-1>
</el-tab-pane>
<el-tab-pane label="비밀번호변경">
<menu-2></menu-2>
</el-tab-pane>
<el-tab-pane label="회원탈퇴">
<menu-3></menu-3>
</el-tab-pane>
</el-tabs>
</el-card>
</div>
//ファイル名:mypage/Menu 1.vue<div>
<el-form :inline="true" class="demo-form-inline" style="margin-bottom:-20px">
<el-form-item label="나이" label-width="120px">
<el-input v-model="member.userage" ref="userage" size="mini" placeholder="이름"></el-input>
</el-form-item>
</el-form>
<el-form :inline="true" class="demo-form-inline" style="margin-bottom:-20px">
<el-form-item label="이메일" label-width="120px">
<el-input v-model="member.useremail1" ref="useremail" size="mini" placeholder="이메일"></el-input>
</el-form-item>
<el-form-item >@</el-form-item>
<el-form-item >
<el-select v-model="member.useremail2" ref="useremail1" size="mini" placeholder="선택">
<el-option v-for="tmp in emailOption" :key="tmp"
:label="tmp" :value="tmp"></el-option>
</el-select>
</el-form-item>
</el-form>
<el-form :inline="true" class="demo-form-inline" style="margin-bottom:-20px">
<el-form-item label=" " label-width="120px">
<el-button type="primary" size="mini" @click="handleUpdate">수정하기</el-button>
</el-form-item>
</el-form>
</div>
Reference
この問題について(20220106), 我々は、より多くの情報をここで見つけました https://velog.io/@gegus1220/20220106テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol