043 - 비밀번호 변경
남기용 332

지난 시간에 비밀번호 찾기용 이메일 발송까지 되었고 메일로 발송된 변경 링크를 타고 온 회원에게 비밀번호를 변경할 수 있는 페이지를 제공하도록 할께요

먼저 ModifyPassword.vue 를 작성합니다.

<template>
	<div class="d-flex justify-center align-center" style="height: 100%">
    <v-card max-width="400" width="100%" elevation="10">
      <v-card-subtitle>
				변경하실 비밀번호를 입력하세요.
			</v-card-subtitle>
			<v-form @submit.prevent="save" ref="form" v-model="valid" lazy-validation>
				<v-card-text>
					<input-password
						v-model="form.password"
						label="비밀번호"
						prepend-icon="mdi-lock"
						:rules="rules.password()"
					/>
					<input-password
						v-model="confirmPw"
						label="비밀번호 확인"
						prepend-icon="mdi-lock-check"
						:rules="[rules.matchValue(form.password)]"
					/>
				</v-card-text>
				<v-card-actions>
					<v-btn type="submit" block color="primary" :loading="loading">
						비밀번호 변경
					</v-btn>
				</v-card-actions>	
			</v-form>
			<v-card-text class="mt-n4">
				<v-btn to="/login" block >로그인</v-btn>
			</v-card-text>
    </v-card>
  </div>
</template>

<script>
import { mapActions } from 'vuex';
import validateRules from '../../../util/validateRules';
import InputPassword from '../../components/InputForms/InputPassword.vue'
export default {
  components: { InputPassword },
	name : "ModifyPassword",
	data() {
		return {
			valid : true,
			form : {
				password : "abcd1234",
				hash : this.$route.params.hash
			},
			confirmPw : "abcd1234",
			loading : false,
		}
	},
	computed : {
		rules : () => validateRules,
	},
	methods : {
		...mapActions('user', ['modifyPassword']),
		async save() {
			this.$refs.form.validate();
			await this.$nextTick();
			if(!this.valid) return;
			this.loading = true;
			const data = await this.modifyPassword(this.form); 
			this.loading = false;
			if(data) {
				this.$toast.info('비밀번호가 변경되었습니다.');
				this.$router.push('/login');
			}
		}
	}
}
</script>

그리고 라우트에 규칙을 추가 하도록 합니다.

Error 규칙 위에 작성해 주세요.

// 생략...
	{
		path: '/modifyPassword/:hash',
		name: 'NoAuthModifyPassword',
		component: () => import(/* webpackChunkName: "modifyPassword" */ '../views/member/ModifyPassword.vue')
	},

스토어 user.js에 modifyPassword 함수를 추가합니다.

// 생략...
export const actions = {
	// 생략...
	async modifyPassword(ctx, form) {
		const {$axios} = Vue.prototype;
		const data = await $axios.patch(`/api/member/modifyPassword`, form);
		return data;
	}
}

api/member.js에 라우터 를 추가합니다.

// 비밀번호 변경
router.patch('/modifyPassword', async (req, res) => {
	const result = await modelCall(memberModel.modifyPassword, req.body);
	res.json(result);
});

memberModel.js 에 modifyPassword 함수를 추가합니다.

	async modifyPassword(data) {
		// 유효시간이 경과된 거 삭제
		const delQuery = `DELETE FROM ${TABLE.SEND_MAIL} WHERE sm_type=1 AND sm_expire_at < NOW()`;
		await db.execute(delQuery);
		// 유효시간 안에 해쉬로 검색
		const sql = {
			query: `SELECT sm_to FROM ${TABLE.SEND_MAIL} WHERE sm_type=? AND sm_hash=? AND sm_expire_at > NOW()`,
			values: [1, data.hash],
		};
		const [[row]] = await db.execute(sql.query, sql.values);
		// 없으면 에러
		if (!row) {
			throw new Error('시간이 만료되었거나 이미 처리되었습니다.');
		}
		// 있으면 비밀번호를 변경 하고
		const mb_email = row.sm_to;
		const mb_password = await jwt.generatePassword(data.password);
		const upSql = sqlHelper.Update(TABLE.MEMBER, { mb_password }, { mb_email });
		const [upRes] = await db.execute(upSql.query, upSql.values);

		// 처리한거 삭제
		const delSql = sqlHelper.DeleteSimple(TABLE.SEND_MAIL, {sm_hash : data.hash});
		db.execute(delSql.query, delSql.values);
		return upRes.affectedRows == 1;
	},

SqlHeler.js에 DeleteSimple 함수를 추가합니다.

	DeleteSimple(table, data) {
		let query = `DELETE FROM ${table}`;
		const where = [];
		const values = [];

		if (data) {
			const keys = Object.keys(data);
			for (key of keys) {
				where.push(`${key}=?`);
				values.push(data[key]);
			}
			query += ` WHERE ` + where.join(' AND ');
		} else {
			throw new Error('DELETE 구문에는 WHERE절이 있어야 합니다.');
		}

		return { query, values };
	},
회원로그인 후 댓글을 작성하실 수 있습니다. 로그인
© 2024 ezcode all right reserved.