개발 전 과정

그 동안의 개발과정은 해당 카테고리 + Node.js 카테고리에서 볼 수 있습니다.

 

 

 

백엔드

 

backend/app.js

var createError = require('http-errors');
var express = require('express');
var path = require('path');
const history = require('connect-history-api-fallback');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
const cors = require("cors");
const mongoose = require('mongoose');
var session = require('express-session');
var indexRouter = require('./routes/index');

require('dotenv').config();

var app = express();



// view engine setup

var views = [
  //path.join(__dirname, '../public', 'index.html')
  path.join(__dirname, 'views')
]

app.set('views', views);
app.set('view engine', 'ejs');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser(process.env.cookie_secret));

app.use(session({
  secret : process.env.session_secret,
  resave : false,
  saveUninitialized : false,
  cookie : {
    maxAge : (3.6e+6)*12,
    httpOnly : false
  },
  store : require('mongoose-session')(mongoose)
}))

app.use('/', indexRouter);
app.use(history());

app.use(express.static(path.join(__dirname, 'public')));

app.use(
  cors({
    origin : 'http://olrang.shop:3000',
    credentials : true,
  })
);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});




  // mongodb 미들웨어
mongoose.connect(  // DB 연결
  'mongodb://olrang.shop:27017/mydbname',  // DB 주소
  { useNewUrlParser : true, useUnifiedTopology : true,},
  function(err) {
    if(err){
      console.error('mongodb connection error!!!', err);
    }
    console.log('mongodb connected!!')  // 연결 성공시 출력되는 메시지
  }
);





var userControll=require('./routes/index.js');

app.use('/signup',userControll); 

app.use('/login', userControll);

app.use('/logout', userControll);

app.use('/aptitude',userControll); 

app.use('/secession',userControll); 

app.use('/api/mypage',userControll);

app.use('/mypage',userControll);




module.exports = app;

 

Express, cookie, mongodb, express-session을 사용했습니다.

 

cookie, session의 secretkey는 dotenv를 사용해서 분리했습니다.

 

https가 아닌 http를 사용했기 때문에 보안옵션은 사용하지 않았습니다.

 

 

 

backend/routes/index.js

var express = require('express');
var path = require('path');
var router = express.Router();
router.use(express.urlencoded({extended:true}));
router.use(express.json())
var User = require('./mongodbuser');  // DB 스키마 파일 참조
var Product = require('./mongodbproduct'); // DB 스키마 파일 참조
var Order = require('./mongodborder'); // DB 스키마 파일 참조
const crypto = require('crypto'); // 패스워드 암호화 모듈


/* GET home page. */
router.get('/', function(req, res, next) {
  res.sendFile(path.join(__dirname, '../public', 'index.html'));
  //res.render('index', { title: 'Express' });
});

router.post('/signup', (request, response) => { //회원 가입

  var ck = true;
  if(request.body.id == request.body.password){  //request.body는 웹 input 태그에서 값 가져오는 기능. body 뒤에는 input 태그의 name 값을 써야함
    try{
      response.send("<script>alert('아이디와 비밀번호는 서로 달라야 합니다.');location.href='/signup';</script>");
      }catch (exception) {
        response.redirect('/signup');
      }
    ck= false;
  }
  
  if (request.body.id == ''){  // 공백 입력 방지
    try{
      response.send("<script>alert('id가 입력되지 않았습니다.');location.href='/signup';</script>");
      }catch (exception) {
        response.redirect('/signup');
      }
  }

  if (request.body.password == ''){
    try{
      response.send("<script>alert('password가 입력되지 않았습니다.');location.href='/signup';</script>");
      }catch (exception) {
        response.redirect('/signup');
      }
  }

  if (request.body.name == ''){
    try{
      response.send("<script>alert('name이 입력되지 않았습니다.');location.href='/signup';</script>");
      }catch (exception) {
        response.redirect('/signup');
      }
  }

  if (request.body.phone == ''){
    try{
      response.send("<script>alert('phone number가 입력되지 않았습니다.');location.href='/signup';</script>");
      }catch (exception) {
        response.redirect('/signup');
      }
  }

  User.find((err, users) => { //id 중복체크 
      if(users.id == request.body.id){  // users는 DB 유저 목록  
          ck = false;
          try{
            response.send("<script>alert('이미 존재하는 아이디입니다.');location.href='/signup';</script>");
            }catch (exception) {
              response.redirect('/signup');
            }
        }
      });

    if(ck==true){
      var password = request.body.password;
      crypto.randomBytes(64, (err, buf) => {  // 패스워드 암호화
        const salt = buf.toString('base64')
        crypto.pbkdf2(password, salt, 107529, 64, 'sha512', (err, key) => {
          User.create ({ //DB 생성
            id:request.body.id,
            password:(key.toString('base64')),
            salt : salt,  // salt 값 저장
            name:request.body.name,
            phone:request.body.phone,
          }); 
        });
      });
    


      response.redirect('/login');
    }



});



router.post('/login', (req, res) => {

  User.findOne({id : req.body.id},(err, users) => { // id를 먼저 체크해서
    if(!users || err){ //id가 DB에 없으면(즉, id가 틀렸거나 회원가입이 안되어 있거나) 
      try{
        res.send("<script>alert('아이디가 틀렸습니다.');location.href='/login';</script>");
        }catch (exception) {
          res.redirect('/login');
        }
      
    }
    else {
    var cpassword = req.body.password; // 사용자가 입력한 패스워드를 가져와서
    crypto.randomBytes(64, (err, buf) => {
      crypto.pbkdf2(cpassword, users.salt, 107529, 64, 'sha512', (err, key) => {
        cpassword = key.toString('base64') // DB에 저장했던 동일한 방식으로 암호화 
        
        if (users.password == cpassword) { // 저장된 패스워드와 암호화된 입력받은 패스워드 비교
          // res.header('Access-Control-Allow-Origin', 'olrang.shop:3000');
          // res.header("Access-Control-Allow-Credentials", true);
          /*res.cookie('session', users.name, {
          maxAge : (3.6e+6)*12 //12시간
          // secure : true,  // https 쓸 때 사용 가능한 보안 옵션
          // sameSite : 'none', //secure 쓸 때 사용 가능한 옵션
          // domain : 'olrang.shop:3000/login',
          // httpOnly : true,  // js에서 쿠키에 접근 못하게 하는 옵션
        }); */
            req.session.userinfo = users.phone;
           
        res.redirect('/');
        } else { // 패스워드 틀렸을 때
          try{
            res.send("<script>alert('비밀번호가 틀렸습니다.');location.href='/login';</script>");
            }catch (exception) {
              res.redirect('/login');
            }
          
        }
      });
    });
  }
  })
}) 

router.get('/logout', (req, res) => {
      if(!req.session) {  // 세션 없을 때
        res.redirect('/');
      } else {
        req.session.destroy(()=>{
          res.clearCookie('connect.sid');
          res.redirect('/');
      });
      }
})

router.get('/api/mypage', (req, res) => { //마이페이지에 띄울 db 정보 가져오기
    var mydata = {phone : req.session.userinfo};
    res.json(mydata);
})

router.post('/mypage', (req, res) => { //마이페이지 정보 수정
    if(req.body.phone == ''){
      try{
        res.send("<script>alert('값을 입력해주세요');location.href='/mypage';</script>");
        }catch (exception) {
          res.redirect('/mypage');
        }
    } else { 
        users.updateOne({$set : {phone : req.body.phone}}).exec();
        res.redirect('/');
    }
    res.redirect('/');

})



router.post('/secession', (req, res) => { // 탈퇴
  User.findOne({phone : req.sesssion.userinfo},(err, users) => { 
      if(!req.sesssion.userinfo || err) {  // 정보/쿠키 없거나 에러 났을 때
        res.redirect('/');
      } else {
        users.deleteOne();
        req.session.destroy(()=>{
        res.clearCookie('connect.sid');
        res.redirect('/');
      }); 
    }
  })
})

router.post('/aptitude', async (req, res) => {
  // 프론트에서 결제 api 먼저 실행 후 
  try {
    // const { imp_uid, merchant_uid } = req.body; // req의 body에서 imp_uid, merchant_uid 추출
    
    const imp_uid = req.body.imp_uid;
    const merchant_uid = req.body.merchant_uid;


    // 액세스 토큰(access token) 발급 받기
    const getToken = await axios({
      url: "https://api.iamport.kr/users/getToken",
      method: "post", // POST method
      headers: { "Content-Type": "application/json" }, // "Content-Type": "application/json"
      data: {
        imp_key: "2406300329155625", // REST API키
        imp_secret: "81a24245bfda5c8ef9dd9098e973245259ca027de69f48bbee3d06bc49d9f57355a1fe6d6a663556" // REST API Secret
      }
    });
    const { access_token } = getToken.data.response; // 인증 토큰


      // imp_uid로 아임포트 서버에서 결제 정보 조회
      const getPaymentData = await axios({
        url: `https://api.iamport.kr/payments/${imp_uid}`, // imp_uid 전달
        method: "get", // GET method
        headers: { "Authorization": access_token } // 인증 토큰 Authorization header에 추가
      });
      const paymentData = getPaymentData.data.response; // 조회한 결제 정보

      // DB에서 결제되어야 하는 금액 조회
      const order = await Product.findOne({name :"aptitude"});
      const amountToBePaid = order.amount; // 결제 되어야 하는 금액


      // 결제 검증하기
      const { amount, status } = paymentData;
      if (amount === amountToBePaid && req.cookies.session) { // 결제 금액 일치. 결제 된 금액 === 결제 되어야 하는 금액
        await Order.create({  // DB에 결제 정보 저장
          number : merchant_uid,
          name : req.cookies.session,
          product : req.body.name,
          amount : req.body.amount
        }); 


        switch (status) {
          case "paid": // 결제 완료
            console.log("결제 성공");  
          //res.send({ status: "success", message: "일반 결제 성공" });
            break;
        }
      } else { // 결제 금액 불일치. 위/변조 된 결제
        console.log("위조된 결제 시도");
        //throw { status: "forgery", message: "위조된 결제시도" };
      }
    } catch (e) {
      res.status(400).send(e);
    }
  });

  router.post('/homelover', async (req, res) => {
    // 프론트에서 결제 api 먼저 실행 후 
    try {
      // const { imp_uid, merchant_uid } = req.body; // req의 body에서 imp_uid, merchant_uid 추출
      
      const imp_uid = req.body.imp_uid;
      const merchant_uid = req.body.merchant_uid;
  
  
      // 액세스 토큰(access token) 발급 받기
      const getToken = await axios({
        url: "https://api.iamport.kr/users/getToken",
        method: "post", // POST method
        headers: { "Content-Type": "application/json" }, // "Content-Type": "application/json"
        data: {
          imp_key: "2406300329155625", // REST API키
          imp_secret: "81a24245bfda5c8ef9dd9098e973245259ca027de69f48bbee3d06bc49d9f57355a1fe6d6a663556" // REST API Secret
        }
      });
      const { access_token } = getToken.data.response; // 인증 토큰
  
  
        // imp_uid로 아임포트 서버에서 결제 정보 조회
        const getPaymentData = await axios({
          url: `https://api.iamport.kr/payments/${imp_uid}`, // imp_uid 전달
          method: "get", // GET method
          headers: { "Authorization": access_token } // 인증 토큰 Authorization header에 추가
        });
        const paymentData = getPaymentData.data.response; // 조회한 결제 정보
  
        // DB에서 결제되어야 하는 금액 조회
        const order = await Product.findOne({name :"homelover"});
        const amountToBePaid = order.amount; // 결제 되어야 하는 금액
  
  
        // 결제 검증하기
        const { amount, status } = paymentData;
        if (amount === amountToBePaid && req.cookies.session) { // 결제 금액 일치. 결제 된 금액 === 결제 되어야 하는 금액
          await Order.create({  // DB에 결제 정보 저장
            number : merchant_uid,
            name : req.cookies.session,
            product : req.body.name,
            amount : req.body.amount
          }); 
  
  
          switch (status) {
            case "paid": // 결제 완료
              console.log("결제 성공");  
            //res.send({ status: "success", message: "일반 결제 성공" });
              break;
          }
        } else { // 결제 금액 불일치. 위/변조 된 결제
          console.log("위조된 결제 시도");
          //throw { status: "forgery", message: "위조된 결제시도" };
        }
      } catch (e) {
        res.status(400).send(e);
      }
    });


    router.post('/past', async (req, res) => {
      // 프론트에서 결제 api 먼저 실행 후 
      try {
        // const { imp_uid, merchant_uid } = req.body; // req의 body에서 imp_uid, merchant_uid 추출
        
        const imp_uid = req.body.imp_uid;
        const merchant_uid = req.body.merchant_uid;
    
    
        // 액세스 토큰(access token) 발급 받기
        const getToken = await axios({
          url: "https://api.iamport.kr/users/getToken",
          method: "post", // POST method
          headers: { "Content-Type": "application/json" }, // "Content-Type": "application/json"
          data: {
            imp_key: "2406300329155625", // REST API키
            imp_secret: "81a24245bfda5c8ef9dd9098e973245259ca027de69f48bbee3d06bc49d9f57355a1fe6d6a663556" // REST API Secret
          }
        });
        const { access_token } = getToken.data.response; // 인증 토큰
    
    
          // imp_uid로 아임포트 서버에서 결제 정보 조회
          const getPaymentData = await axios({
            url: `https://api.iamport.kr/payments/${imp_uid}`, // imp_uid 전달
            method: "get", // GET method
            headers: { "Authorization": access_token } // 인증 토큰 Authorization header에 추가
          });
          const paymentData = getPaymentData.data.response; // 조회한 결제 정보
    
          // DB에서 결제되어야 하는 금액 조회
          const order = await Product.findOne({name :"pastpotion"});
          const amountToBePaid = order.amount; // 결제 되어야 하는 금액
    
    
          // 결제 검증하기
          const { amount, status } = paymentData;
          if (amount === amountToBePaid && req.cookies.session) { // 결제 금액 일치. 결제 된 금액 === 결제 되어야 하는 금액
            //const useraddress = User.findOne({name : req.cookies.session});
            await Order.create({  // DB에 결제 정보 저장
              number : merchant_uid,
              name : req.cookies.session,
              product : req.body.name,
              amount : req.body.amount
            }); 
    
    
            switch (status) {
              case "paid": // 결제 완료
                console.log("결제 성공");  
              //res.send({ status: "success", message: "일반 결제 성공" });
                break;
            }
          } else { // 결제 금액 불일치. 위/변조 된 결제
            console.log("위조된 결제 시도");
            //throw { status: "forgery", message: "위조된 결제시도" };
          }
        } catch (e) {
          res.status(400).send(e);
        }
      });


      router.post('/friendadd', async (req, res) => {
        // 프론트에서 결제 api 먼저 실행 후 
        try {
          // const { imp_uid, merchant_uid } = req.body; // req의 body에서 imp_uid, merchant_uid 추출
          
          const imp_uid = req.body.imp_uid;
          const merchant_uid = req.body.merchant_uid;
      
      
          // 액세스 토큰(access token) 발급 받기
          const getToken = await axios({
            url: "https://api.iamport.kr/users/getToken",
            method: "post", // POST method
            headers: { "Content-Type": "application/json" }, // "Content-Type": "application/json"
            data: {
              imp_key: "2406300329155625", // REST API키
              imp_secret: "81a24245bfda5c8ef9dd9098e973245259ca027de69f48bbee3d06bc49d9f57355a1fe6d6a663556" // REST API Secret
            }
          });
          const { access_token } = getToken.data.response; // 인증 토큰
      
      
            // imp_uid로 아임포트 서버에서 결제 정보 조회
            const getPaymentData = await axios({
              url: `https://api.iamport.kr/payments/${imp_uid}`, // imp_uid 전달
              method: "get", // GET method
              headers: { "Authorization": access_token } // 인증 토큰 Authorization header에 추가
            });
            const paymentData = getPaymentData.data.response; // 조회한 결제 정보
      
            // DB에서 결제되어야 하는 금액 조회
            const order = await Product.findOne({name :"friendadd"});
            const amountToBePaid = order.amount; // 결제 되어야 하는 금액
      
      
            // 결제 검증하기
            const { amount, status } = paymentData;
            if (amount === amountToBePaid && req.cookies.session) { // 결제 금액 일치. 결제 된 금액 === 결제 되어야 하는 금액
              // const useraddress = User.findOne({name : req.cookies.session});
              await Order.create({  // DB에 결제 정보 저장
                number : merchant_uid,
                name : req.cookies.session,
                // address : useraddress.address,
                product : req.body.name,
                amount : req.body.amount
              }); 
      
      
              switch (status) {
                case "paid": // 결제 완료
                  console.log("결제 성공");  
                //res.send({ status: "success", message: "일반 결제 성공" });
                  break;
              }
            } else { // 결제 금액 불일치. 위/변조 된 결제
              console.log("위조된 결제 시도");
              //throw { status: "forgery", message: "위조된 결제시도" };
            }
          } catch (e) {
            res.status(400).send(e);
          }
        });

module.exports = router;

 

 

다음주소API를 사용하긴 하지만 개발 도중, 주소 값을 DB에 저장할 필요가 없다고 느껴져서 DB에 주소 값을 저장하지 않았습니다.

(택배 배송 추적을 구현해볼 수 없어서 주소를 저장해야할 필요성을 느끼지 못했습니다.)

 

마이페이지 접근 제한은 미들웨어를 사용하지 않고 FRONTEND에서 메인 페이지로 이동하도록 구현했습니다.

(아래에 코드가 첨부되어 있습니다.)

 

i'mport 결제 API를 사용했고 테스트 결제까지 실행되지만 사업자등록번호가 없어서 보안처리(액세스토큰발급, DB접근)는 실행되지 않습니다.

 

 

 

프론트엔드

 

모든 페이지가 아닌 주요 기능이 포함되어있는 페이지 코드만 있습니다.

또한 가독성을 위해 CSS 코드는 제외했습니다.

 

 

회원가입(다음주소API)

<template>

<div class="signuppage">
    <h1>회원 가입</h1><br><br><br>
    <div class="inputbox">
    <form action="/signup" method="post">
        <h3>ADDRESS</h3>
        <input type="text" id="postcode" name="postcode" placeholder="우편번호">
        <button type="button" @click="search()">우편번호 찾기</button><br>
        <input type="text" id="roadAddress" name = "roadAddress" placeholder="도로명주소">
        <input type="text" id="jibunAddress" name = "jibunAddress" placeholder="지번주소">
        <span id="guide" style="color:#000;display:none"></span>
        <input type="text" id="detailAddress" name="detailAddress" placeholder="상세주소">
        <input type="text" id="extraAddress" name="extraAddress" placeholder="참고항목">
      <h3>ID</h3>
      <input type="text" name="id" pattern="^(?=.*\d)(?=.*[a-z]).{5,15}" placeholder="최소 5자 이상, 숫자 필수, 영문"> <br>
        <h3>PASSWORD</h3>
       <input type="text" name="password" pattern="^(?=.*\d)(?=.*[a-z]).{8,15}" placeholder="최소 8자 이상, 숫자 필수, 영문"> <br>
        <h3>NAME</h3>
       <input type="text" name="name" maxlength="4" pattern="^[가-힣]+$" placeholder="한글만, 최대 4자"> <br>
       <h3>PHONE NUMBER</h3>
       <input type="text" name="phone" maxlength="11" pattern="^(\d{3}).*(\d{3}).*(\d{4})" placeholder="전화번호 입력"> <br>
      <button @click="signup()">회원 가입</button>
    </form>
    </div>
    </div>
</template>


<script>

import axios from 'axios'

export default {
    name : "SignUpPage",

    data (){
        return {
            id : '',
            password : '',
            name : '',
            address : ''

        }
    },

    methods : {
        signup() {
            axios.post( "http://olrang.shop:3000/signup", {
                    id : this.id,
                    password : this.password,
                    name : this.name,
                    // address : this.postcode + this.roadAddress + this.jibunAddress,
                    phone : this.phone,
                }).then((response) => {
                        this.response = response
                    
                }).catch((error) => {  
                    this.error=error  
               
                
            });
        },

        search(){
            new window.daum.Postcode({
            oncomplete: (data) => {
                // 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분.

                // 도로명 주소의 노출 규칙에 따라 주소를 표시한다.
                // 내려오는 변수가 값이 없는 경우엔 공백('')값을 가지므로, 이를 참고하여 분기 한다.
                var roadAddr = data.roadAddress; // 도로명 주소 변수
                var extraRoadAddr = ''; // 참고 항목 변수

                // 법정동명이 있을 경우 추가한다. (법정리는 제외)
                // 법정동의 경우 마지막 문자가 "동/로/가"로 끝난다.
                if(data.bname !== '' && /[동|로|가]$/g.test(data.bname)){
                    extraRoadAddr += data.bname;
                }
                // 건물명이 있고, 공동주택일 경우 추가한다.
                if(data.buildingName !== '' && data.apartment === 'Y'){
                   extraRoadAddr += (extraRoadAddr !== '' ? ', ' + data.buildingName : data.buildingName);
                }
                // 표시할 참고항목이 있을 경우, 괄호까지 추가한 최종 문자열을 만든다.
                if(extraRoadAddr !== ''){
                    extraRoadAddr = ' (' + extraRoadAddr + ')';
                }

                // 우편번호와 주소 정보를 해당 필드에 넣는다.
                document.getElementById('postcode').value = data.zonecode;
                document.getElementById("roadAddress").value = roadAddr;
                document.getElementById("jibunAddress").value = data.jibunAddress;
                
                // 참고항목 문자열이 있을 경우 해당 필드에 넣는다.
                if(roadAddr !== ''){
                    document.getElementById("extraAddress").value = extraRoadAddr;
                } else {
                    document.getElementById("extraAddress").value = '';
                }

                var guideTextBox = document.getElementById("guide");
                // 사용자가 '선택 안함'을 클릭한 경우, 예상 주소라는 표시를 해준다.
                if(data.autoRoadAddress) {
                    var expRoadAddr = data.autoRoadAddress + extraRoadAddr;
                    guideTextBox.innerHTML = '(예상 도로명 주소 : ' + expRoadAddr + ')';
                    guideTextBox.style.display = 'block';

                } else if(data.autoJibunAddress) {
                    var expJibunAddr = data.autoJibunAddress;
                    guideTextBox.innerHTML = '(예상 지번 주소 : ' + expJibunAddr + ')';
                    guideTextBox.style.display = 'block';
                } else {
                    guideTextBox.innerHTML = '';
                    guideTextBox.style.display = 'none';
                }
            }
        }).open();
        }
    }
}


</script>

 

 

상품페이지(i'mport 결제 API)

<template>
  <div class="pastintro">
      <h1>[Best] 원하는 과거로 갈 수 있는 포션</h1><br><br>
      <h3>해당 포션은 14세 이상부터 권장합니다.</h3><br><br><br>
        <img :src="require('@/assets/pastpotion.jpg')">
      <div class="info">
        <h2>사용 대상</h2>
        <h2 v-for="item in items" :key="item">{{item.message}} </h2><br><br><br>
        <h2>사용법</h2>
        <h2 v-for="use in list" :key="use">{{use.message}} </h2><br><br><br>
        <h2>주의 사항</h2>
        <h2 v-for="warn in warns" :key="warn">{{warn.message}} </h2><br><br><br>
        <h3>구매 전, 구매하실 포션의 이름과 사진이 맞는 지 확인해주세요.</h3><br><br><br><br>
        <img :src="require('@/assets/pastpotion.jpg')">
        <div class="purchase">
        <h1>[Best] 원하는 과거로 갈 수 있는 포션</h1><br><br>
        <h1>1500 원</h1>
        <button type="button" @click="past()">구매하기</button>
        </div>
    </div>
  </div>
</template>

<script>

import jQuery from 'jquery'

export default {
    name : "PastIntro",
    data (){
        return {
            items : [
                {message : '과거가 그리운 사람'},
                {message : '어린 시절로 돌아가고 싶은 사람 등'}
                
            ],

            list : [
                {message : '자기 전, 시간 차를 두지 않고 한 번에 끝까지 마시면 됩니다.'},
                {message : '눈을 감고 원하는 과거를 떠올리면 됩니다.'},
                {message : '꿈 속에서 과거에 머무를 수 있는 시간은 실제 수면 시간과 동일합니다.'},
                
            ],

            warns : [
                {message : '최소 2주에 1번만 마시는 것을 권장합니다.'},
                {message : '꿈 속에서의 일은 절대 현재, 미래에 영향을 미치지 않습니다.'}
                

            ]
        }
    },
methods : {
    past(){
        var IMP = window.IMP;
            IMP.init("imp07168267");

            IMP.request_pay({ // param
                pg: "kakao", // PG사 선택
                pay_method: "card", // 지불 수단
                merchant_uid: 'merchant_' + new Date().getTime(), //가맹점에서 구별할 수 있는 고유한id
                name: "[Best] 원하는 과거로 갈 수 있는 포션", // 상품명
                amount: 1500, // 가격
                digital: true, // 실제 물품인지 무형의 상품인지(핸드폰 결제에서 필수 파라미터)
                app_scheme : '' // 돌아올 app scheme
            }, function (rsp) { // callback
                
                if (rsp.success) {
                    jQuery.ajax({
                        url: "http://olrang.shop:3000/aptitude", // 가맹점 서버
                        method: "POST",
                        headers: { "Content-Type": "application/json" },
                        data: {
                            imp_uid: rsp.imp_uid,
                            merchant_uid: rsp.merchant_uid
                            //기타 필요한 데이터가 있으면 추가 전달
                        }
                    }).done(function (data) {
                        // 가맹점 서버 결제 API 성공시 로직
                        switch(data.status){
                        case "success":
                            alert("결제 성공!");
                        break;
               
                        }
                    });

                } else {
                    // 결제 실패 시 로직,
                alert("결제 실패. 에러 내용 : "+rsp.error_msg);
                }
            });
    }
}

}
</script>

 

 

마이페이지(페이지 접근 제한)

<template>
<div class = "mypage">
    <h2>개인정보 수정</h2> <br>
    <h3>기존 번호 : {{mydata}}</h3>
    <form action="/mypage" method="post">
        <input type="text" name="phone" maxlength="11" pattern="^(\d{3}).*(\d{3}).*(\d{4})" placeholder="전화번호"> <br>
    <button @click="update()">수정하기</button>
    </form>
</div>
  
</template>

<script>
import axios from 'axios'

export default {
    name : "MyPage",
    data(){
        return{
            mydata:''
        }
    },
        created() {
            axios.get('http://olrang.shop:3000/api/mypage',  { 
                withCredentials: true,
            }).then((response) => { 
                this.mydata = response.data.phone
                if(this.mydata == undefined)
                    this.$router.replace('/') // 로그인 안되어 있을 경우 마이페이지 접근 제한
                
            }).catch((error) => {  
                this.error=error    
            
                
            })
        },

        method : {
            update(){
            axios.post('http://olrang.shop:3000/mypage',  { 
                withCredentials: true,
                phone : this.phone,
            }).then((response) => { 
                this.response = response
                
            }).catch((error) => {  
                this.error=error    
            })

            }
        }
    }

</script>

 

 

긴 글 읽어주셔서 감사합니다.