فصل پیوست ۲: دریافت توکن احراز هویت در مرورگر

Receive Authentication Tokens in the Browser

Vue.JS 2 - فصل پیوست 2: دریافت توکن احراز هویت در مرورگر - قسمت 120

در قسمت قبل با موفقیت کاربران را ثبت نام کرده و در عملیات sign in، توکن امنیتی را از آن ها دریافت می کردیم. مسئله اینجاست که این توکن امنیتی باید در مرورگر کاربر ذخیره شود تا هر زمانی که درخواستی داشتیم، توکن را نیز به همراه درخواست به سرور ارسال کنیم. در پروژه آماده ای که به شما دادم فایلی به نام store.js وجود دارد که فقط کلیت کار را در خود دارد:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {

  },
  mutations: {

  },
  actions: {

  },
  getters: {

  }
})

من در اینجا یک store تعریف کرده ام که طرح کلی یک سیستم state management را به ما نشان می دهد و در فصل vuex مفصلا در مورد تمام آن ها صحبت کرده ایم. اولین خصوصیتی که در State اضافه می کنیم باید همان token باشد که من نامش را idToken می گذارم. سپس باید یک userId نیز داشته باشیم تا id کاربر مشخص شود:

state: {
  idToken: null,
  userId: null
},

همچنین برای action ها حداقل به دو مورد نیاز داریم: یک action برای sign up (ثبت نام) و یک action برای login (ورود به حساب کاربری) بنابراین بدنه این دو درخواست را نیز می نویسم:

actions: {
  signup({ commit }, authData) {

  },
  login({ commit }, authData) {

  }
},

مثل همیشه commit را دریافت کرده ایم ولی به عنوان payload، اطلاعات مربوط به احراز هویت را خواهیم گرفت که من نامشان را authData گذاشته ام. در مرحله بعد به فایل signup.vue می رویم. در حال حاضر کدهای ارسال درخواست ما با axios و به صورت زیر نوشته شده اند:

onSubmit() {
  const formData = {
    email: this.email,
    age: this.age,
    password: this.password,
    confirmPassword: this.confirmPassword,
    country: this.country,
    hobbies: this.hobbyInputs.map(hobby => hobby.value),
    terms: this.terms
  };
  console.log(formData);
  axios
    .post("/accounts:signUp?key=AIzaSyDtirb936QLEAL9Hbkn1st5c3cF3U7_cFI", {
      email: formData.email,
      password: formData.password,
      returnSecureToken: true
    })
    .then(res => console.log(res))
    .catch(error => console.log(error));
}

من فقط قسمت مربوط به axios از کد بالا را کات کرده و به store.js می برم. همچنین یادتان باشد که دستور import مربوط به Axios را نیز از signup.vue برداشته و به بالای store.js انتقال بدهید. کدهای ارسال درخواست با axios نیز باید به action اول ما یعنی signup اضافه شود. ابتدا دستور import را به فایل store.js می برم:

import Vue from 'vue'
import Vuex from 'vuex'
import axios from "./axios-auth";

سپس کد axios را در action مورد نظر قرار می دهم:

actions: {
  signup({ commit }, authData) {
    axios
      .post("/accounts:signUp?key=AIzaSyDtirb936QLEAL9Hbkn1st5c3cF3U7_cFI", {
        email: formData.email,
        password: formData.password,
        returnSecureToken: true
      })
      .then(res => console.log(res))
      .catch(error => console.log(error));
  },
  login({ commit }, authData) {

  }
},

در مرحله بعدی به فایل signin.vue رفته و همین کار را عینا در آن انجام می دهیم. یعنی ابتدا دستور import را حذف کرده و سپس قسمت axios را کات کنید و در store.js به شکل زیر اضافه نمایید:

actions: {
  signup({ commit }, authData) {
    axios
      .post("/accounts:signUp?key=AIzaSyDtirb936QLEAL9Hbkn1st5c3cF3U7_cFI", {
        email: formData.email,
        password: formData.password,
        returnSecureToken: true
      })
      .then(res => console.log(res))
      .catch(error => console.log(error));
  },
  login({ commit }, authData) {
    axios
      .post(
        "/accounts:signInWithPassword?key=AIzaSyDtirb936QLEAL9Hbkn1st5c3cF3U7_cFI",
        {
          email: formData.email,
          password: formData.password,
          returnSecureToken: true
        }
      )
      .then(res => console.log(res))
      .catch(error => console.log(error));
  }
},

حالا باید کدهای بالا را کمی ویرایش کنیم. به طور مثال ما دیگر نمی توانیم ایمیل را از formData دریافت کنیم چرا که هیچ formData ای در این فایل وجود ندارد بلکه این اطلاعات به صورت payload (همان authData) به ما داده خواهد شد. بنابراین تمام مقادیر formData در کد بالا را حذف کرده و به جای آن ها authData را قرار می دهم:

actions: {
  signup({ commit }, authData) {
    axios
      .post("/accounts:signUp?key=AIzaSyDtirb936QLEAL9Hbkn1st5c3cF3U7_cFI", {
        email: authData.email,
        password: authData.password,
        returnSecureToken: true
      })
      .then(res => console.log(res))
      .catch(error => console.log(error));
  },
  login({ commit }, authData) {
    axios
      .post(
        "/accounts:signInWithPassword?key=AIzaSyDtirb936QLEAL9Hbkn1st5c3cF3U7_cFI",
        {
          email: authData.email,
          password: authData.password,
          returnSecureToken: true
        }
      )
      .then(res => console.log(res))
      .catch(error => console.log(error));
  }
},

حالا کدهایمان تصحیح شده است اما هنوز قصد Commit کردن را نداریم. بهتر است ابتدا کدها را بررسی کنیم تا ببینیم آیا کار می کنند یا نه. برای این کار به فایل signup.vue رفته و action آن را dispatch می کنیم:

onSubmit() {
  const formData = {
    email: this.email,
    age: this.age,
    password: this.password,
    confirmPassword: this.confirmPassword,
    country: this.country,
    hobbies: this.hobbyInputs.map(hobby => hobby.value),
    terms: this.terms
  };
  console.log(formData);
  this.$store.dispatch("signup", {
    email: formData.email,
    password: formData.password
  });
}

همانطور که می بینید به عنوان payload یک شیء ساده جاوا اسکریپتی پاس داده ام که دارای خصوصیات email و password است. حالا همین کار را برای فایل singin.vue نیز انجام می دهیم:

onSubmit() {
  const formData = {
    email: this.email,
    password: this.password
  };
  console.log(formData);
  this.$store.dispatch("login", {
    email: formData.email,
    password: formData.password
  });
}

البته حواستان باشد که این بار باید login را dispatch کنید نه signup را! من این کدها را ذخیره کرده و به مرورگر می روم. در مرورگر به صفحه sign up بروید و با یک ایمیل غیرتکراری دوباره ثبت نام کنید. ایمیل باید غیرتکراری باشد چرا که Firebase ایمیل ها را قبل از ثبت نام بررسی می کند. اگر مثل قبل در کنسول مرورگر پیام firebase را دریافت کردید یعنی همه چیز موفقیت آمیز بوده است و مشکلی نداریم.

حالا باید mutation را بنویسیم. برای این کار به store.js می روم و در قسمت mutations می گویم:

mutations: {
  authUser(state, userData) {
    state.idToken = userData.token;
    state.userId = userData.userId;
  }
},

یعنی هنگامی که این mutation اجرا شود باید idToken و userId را به درستی تنظیم کنیم. حالا این شیء userData از کجا می آید؟ برای دریافت آن باید به actions برگردیم و در قسمت then از هر درخواست axios، این شیء را به همراه commit ارسال نماییم. در حال حاضر فعلا فقط داده ها را  log می کنیم اما می توان گفت:

actions: {
  signup({ commit }, authData) {
    axios
      .post("/accounts:signUp?key=AIzaSyDtirb936QLEAL9Hbkn1st5c3cF3U7_cFI", {
        email: authData.email,
        password: authData.password,
        returnSecureToken: true
      })
      .then(res => {
        console.log(res);
        commit('authUser', {
          token: res.data.idToken,
          userId: res.data.localId
        });
      })
      .catch(error => console.log(error));
  },
  login({ commit }, authData) {
    axios
      .post(
        "/accounts:signInWithPassword?key=AIzaSyDtirb936QLEAL9Hbkn1st5c3cF3U7_cFI",
        {
          email: authData.email,
          password: authData.password,
          returnSecureToken: true
        }
      )
      .then(res => {
        console.log(res);
        commit('authUser', {
          token: res.data.idToken,
          userId: res.data.localId
        });
      })
      .catch(error => console.log(error));
  }
},

همانطور که می بینید من برای هر دو action از یک commit استفاده کرده ام. همچنین res.data به این دلیل است که پاسخ های axios در یک شیء data قرار می گرد بنابراین اول باید res.data را بنویسیم تا به پاسخ Firebase و سپس به فیلد idToken و localId دسترسی داشته باشیم. حالا به مرورگر بروید و یک بار دیگر با یک ایمیل جدید ثبت نام کنید. پس از کلیک روی گزینه submit می توانید vue developer tools را باز کنید و State را مشاهده کنید. اگر کدها را درست نوشته باشید، در قسمت vuex باید شاهد هر دو خصوصیت idToken و userId باشید. این مسئله برای صفحه Sign in نیز صادق است.

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری آموزش رایگان Vue js از صفر تا صد توصیه می‌کند:
نویسنده شوید
دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.