
포스타입 참고
localhost:5000 사용
https://velog.io/@iepppop/json%EC%97%90-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A0%80%EC%9E%A5
vite와 vue로 설치하면 이름이 달라짐
.env.local
VITE_BASE_URL = http://localhost:5000/
main.js
import './assets/main.css'
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import axios from '@/plugins/axios'
import App from './App.vue'
import router from './router'
const app = createApp(App)
app.use(createPinia())
app.use(router)
app.provide('$axios', axios);
app.mount('#app')
plugins/axios.js
import axios from 'axios';
const instance = axios.create({
baseURL: import.meta.env.VITE_BASE_URL, // Vite 환경 변수에서 기본 URL 가져오기
});
export default instance;
signup.js / pinia
전역 설정한 axios 사용
import { ref, computed, inject } from 'vue'
import { defineStore } from 'pinia'
export const useSignUpStore = defineStore('signup', () => {
const axios = inject('$axios');
const submitForm = async (data) => {
try{
const response = await axios.post('/data', data);
} catch(err) {
console.log(err);
}
}
return { submitForm }
})
SingUpView.vue
<template>
<form id="signup-form" @submit.prevent="checkForm()">
<label for="email">이메일</label>
<input type="text" ref="email" placeholder="이메일" id="email" v-model="formData.email" />
...
</form>
</template>
<script setup>
import { ref } from 'vue'
import { useSignUpStore } from '../stores/signup.js'
const store = useSignUpStore()
const formData = ref({
username: '',
email: '',
password: '',
confirmPassword: ''
})
const checkForm = () => {
store.submitForm(formData.value);
}
</script>
기존 사이트에는 없지만 특정 에러 메세지 뜬 부분에 포커싱 되게 추가했다

<template>
<div class="error_msg" :class="[isOpen ? 'open' : '']">
<div class="error_bg"></div>
<div class="error_wrap">
<div class="header">
<span>알림</span>
<button @click="isOpenToggle">x</button>
</div>
<div class="content">
{{ message }}
</div>
<div class="btn_wrap">
<button @click="errMsg">확인</button>
</div>
</div>
</div>
<div class="form-group">
<label for="email">이메일</label>
<input type="text" ref="email" placeholder="이메일" id="email" v-model="formData.email" />
</div>
<div class="form-group">
<label for="password">비밀번호</label>
<input type="password" ref="password" placeholder="비밀번호" id="password" v-model="formData.password" />
</div>
<div class="form-group">
<label for="confirm-password">비밀번호 확인</label>
<input
type="password"
placeholder="비밀번호 확인"
id="confirm-password"
ref="confirmPassword"
v-model="confirmPasswordChk"
/>
</div>
<div class="control">
<div class="custom-control">
<input type="checkbox" id="agreement-1" value="1" v-model="service_agree"/>
<label for="agreement-1">서비스 약관에 동의합니다.</label>
<a href="#" target="_blank">내용보기</a>
</div>
<div class="custom-control">
<input type="checkbox" id="agreement-2" value="2" v-model="privacy_agree"/>
<label for="agreement-2">개인정보 수집 및 이용에 동의합니다. </label>
<a href="#" target="_blank">내용보기</a>
</div>
</div>
<button class="submit" type="submit">회원가입</button>
</form>
</template>
<script setup>
import { onMounted, ref } from 'vue'
import { useSignUpStore } from '../stores/signup.js'
const store = useSignUpStore()
const isOpen = ref(false)
const message = ref('')
const formData = ref({
username: '',
email: '',
password: '',
})
const eleRef = ref();
const confirmPasswordChk = ref('');
const username = ref(null)
const email = ref(null)
const password = ref(null)
const confirmPassword = ref(null)
const service_agree = ref(false)
const privacy_agree = ref(false)
const isOpenToggle = (err) => {
isOpen.value = !isOpen.value
}
const isValidEmail = (email) => {
const emailRegex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
console.log(emailRegex.test(email))
return emailRegex.test(email)
}
const errMsg = () => {
isOpen.value = false;
if(eleRef.value){
eleRef.value.value.focus();
}
}
const checkForm = () => {
if (formData.value.username.length > 5 || formData.value.username.length === 0) {
message.value = '닉네임은 다섯 글자 이하로 입력해 주세요.'
isOpenToggle();
eleRef.value = username;
return;
} else if (!isValidEmail(formData.value.email) || formData.value.email.length === 0) {
message.value = '이메일 주소를 정확히 입력해주세요.'
isOpenToggle();
eleRef.value = email;
return;
} else if(formData.value.password.length === 0){
message.value = '비밀번호를 정확히 입력해주세요.'
isOpenToggle();
eleRef.value = password;
return;
}else if (formData.value.password !== confirmPasswordChk.value) {
message.value = '비밀번호가 일치하지 않습니다.\n 다시 입력해 주세요.'
isOpenToggle();
eleRef.value = confirmPassword;
return;
}else if (!service_agree.value || !privacy_agree.value) {
message.value = '약관에 동의해 주세요.'
isOpenToggle();
eleRef.value = null;
return;
}
store.submitForm(formData.value);
}
</script>

회원가입 버튼을 누르면 이렇게 보내진 것을 확인
하지만 이렇게 보내면 안됨
암호화 ㄱ crytojs 설치
.env.local
VITE_SOME_KEY=20010912 // 추가
plugins/cryto.js <- 파일 만듦
import CryptoJS from 'crypto-js';
// 암호화
export const encryptData = (data) => {
const key = import.meta.env.VITE_SOME_KEY;
const encrypted = CryptoJS.AES.encrypt(JSON.stringify(data), key).toString();
return encrypted;
};
// 복호화
export const decryptData = (data) => {
const key = import.meta.env.VITE_SOME_KEY;
const decrypted = CryptoJS.AES.decrypt(data, key).toString(CryptoJS.enc.Utf8);
return JSON.parse(decrypted);
};
export default {
encryptData,
decryptData
};
SingUpView.vue
import crypto from "../plugins/crypto.js";
const checkForm = () => {
...
formData.value.password = crypto.encryptData(formData.value.password);
store.submitForm(formData.value);
}
그럼 db.json 이렇게 저장이 된다
{
"username": "남예준",
"email": "yejun@plave.vla",
"password": "U2FsdGVkX19+dXFyV9DtyGfzLCg2KYm70TKEZnCovx4=",
"id": 4
}
const userList = ref([])
const store = useSignUpStore()
const loadData = async () => {
try {
const response = await axios.get('/data');
userList.value = response.data;
userList.value.map((item)=>{
item.password = crypto.decryptData(item.password);
})
} catch (err) {
console.error(err);
}
}
onMounted(()=>{
loadData();
})

이렇게 하고 콘솔 창을 보면 복호화가 된 걸 볼 수 있다