vue3 crytojs 회원가입

해적왕·2023년 9월 24일


포스타입 참고

1 json-server

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

2 axios 전역 사용 / vite 사용

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>

3 유효성 검사

기존 사이트에는 없지만 특정 에러 메세지 뜬 부분에 포커싱 되게 추가했다

<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>


회원가입 버튼을 누르면 이렇게 보내진 것을 확인
하지만 이렇게 보내면 안됨

4 cryptoJs

암호화 ㄱ 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
};

4-1 암호화

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
}

4-2 복호화

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();
 })

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

0개의 댓글