Vue Shangpinhui Mall Project-day05 [33. トークン トークンの理解 + 34. ユーザー ログインとユーザー情報を取得するためのトークンの持ち運び + 35. ログアウト]

ここに画像の説明を挿入

33.トークントークンの理解

【トークン:文字列、サーバーがユーザーに発行する身分証明書】
例:古代戦争、兵士のシンボル

34. ユーザーログインは、ユーザー情報を取得するためのトークンを運ぶ

ログイン前に効果を表示:

ここに画像の説明を挿入

ログイン成功後の表示効果:

ここに画像の説明を挿入

コードを変更します。

src/api/index.js

//获取用户信息【需要带着用户的token向服务器要用户信息】
//URL:/api/user/passport/auth/getUserInfo  method:get
export const reqUserInfo = ()=>requests({url:'/user/passport/auth/getUserInfo',method:'get'});

src/api/axios.js

//需要携带token带给服务器
if(store.state.user.token){
        //请求头添加一个字段(userTempId):和后台老师商量好了
        config.headers.token = store.state.user.token;
    }

src/store/loginAndRegister/index.js

import {reqUserInfo} from "@/api";
import {setToken, getToken} from "@/utils/token";

//用户登录
async reqUserLogin({commit}, data) {
	...
	setToken(response.data.token);
	...
}

//获取用户信息
    async reqUserInfo({commit}) {
        let response = await reqUserInfo();
        console.log("******获取用户信息-response:{}", response);
        if (response.code == 200) {
            //用户已经登录成功且获取到token
            commit('REQ_USER_INFO', response.data);
            //返回的是成功的标记
            return "OK";
        } else {
            //返回的是失败的标记
            return Promise.reject(new Error(response.message))
        }
    },
    
REQ_USER_INFO(state, userInfo) {
        state.userInfo = userInfo;
    },
    
userInfo: {}, 
token: getToken(),

src/pages/Home/index.vue

mounted() {
	this.$store.dispatch('reqUserInfo');
}

src/コンポーネント/ヘッダー/index.vue

<p v-if="!userName">
            <span>请</span>
            <!-- 声明式导航:router-link务必要有to属性 -->
            <router-link to="/login">登录</router-link>
            <router-link to="/register" class="register">免费注册</router-link>
</p>
          <!-- 登录了 -->
<p v-else>
            <a>{
   
   {userName}}</a>
            <a class="register">退出登录</a>
</p>

computed: {
	//用户名信息
    userName() {
      return this.$store.state.user.userInfo.name
    }
  }

src/utils/token.js

//存储token
export const setToken = (token) => {
    localStorage.setItem("TOKEN", token);
};
//获取token
export const getToken = () => {
    return localStorage.getItem("TOKEN");
};

注意点1:

質問: 「ユーザー情報の取得」アクションをディスパッチする場所は?

回答: ログインに成功すると Home コンポーネントにジャンプするため、Home コンポーネントが中断されたときに送出されます。

注意点2:

問題: ログインに成功した後、ホーム コンポーネントの左上隅の表示が異なるはずです。

ログイン前に効果を表示:

ここに画像の説明を挿入

ログイン成功後の表示効果:

ここに画像の説明を挿入

答え:与える/

v-if と v-else をラベルに追加して、表示と非表示を制御します。

注 3: ユーザー情報を取得するには、ヘッダーでトークンを渡す必要があります。そうしないと、バックエンドはそれが誰であるかを認識できません。そのため、src/api/axios.js ファイルのリクエスト ヘッダーにトークン情報を追加する必要があります。

//需要携带token带给服务器
if(store.state.user.token){
        //请求头添加一个字段(userTempId):和后台老师商量好了
        config.headers.token = store.state.user.token;
    }

注意点4:

質問: 更新後、ログインしたばかりのユーザーの左上隅に表示されていた情報が消えてしまいました。なぜですか? 具体的な効果を図に示します。

ここに画像の説明を挿入

回答: vuex に格納される情報は非永続的であるため、トークン情報を格納するには永続ストレージ テクノロジを使用する必要があります。

注意点5:

質問: ホーム コンポーネントで更新してもユーザー情報を表示できますが、[詳細コンポーネント|検索コンポーネント] などの他のコンポーネントにジャンプすると表示されなくなりますか? なぜ?

回答: 「ユーザー情報の取得」アクションのディスパッチは、ホーム コンポーネントが中断されたときにのみトリガーされるためです。

仮説の解決策 1: 各コンポーネントが「ユーザー情報を取得する」アクションをコピーして配布すれば効果は得られますが、各コンポーネントを記述するのに時間がかかりすぎます。

仮説 2: アクションが親コンポーネントの APP コンポーネントでディスパッチされるとどうなるでしょうか? APPコンポーネントは一度しかロードされず、ログイン後に更新するとユーザー情報が表示されますが、更新しないと表示されないため、答えはノーです. 明らかに、この解決策は正しくありません.

最終的な解決策: 「ナビゲーション ガード - グローバル ガード」を使用して問題を解決し、Home コンポーネントでディスパッチされた「ユーザー情報の取得」アクションを削除し、すべてを「ナビゲーション ガード」に配置して解決します。詳しくは、ナレッジポイント「36.航海警備の理解」を参照してください。

注意点6:

問題: ユーザーはすでにログインしており、ログイン ページに戻ることはできません。

回答: 最終的な解決策: 「ナビゲーション ガード - グローバル ガード」を使用して問題を解決します。詳しくは、ナレッジポイント「36.航海警備の理解」を参照してください。

35. ログアウトする

コードを変更します。

src/api/index.js

//退出登录
//URL:/api/user/passport/logout  get
export const reqLogout = ()=> requests({url:'/user/passport/logout',method:'get'});

src/store/loginAndRegister/index.js

import {reqLogout} from "@/api";
import {removeToken} from "@/utils/token";

const actions = {
	//用户退出
    async reqLogout({commit}) {
        //只是向服务器发起一次请求,通知服务器清除token
        let response = await reqLogout();
        console.log("******用户退出-response:{}", response);
        //服务器下发token,用户唯一标识符(uuid)
        //将来经常通过带token找服务器要用户信息进行展示
        if (response.code == 200) {
            //用户已经登录成功且获取到token
            commit('REQ_USER_LOGOUT');
            //返回的是成功的标记
            return "OK";
        } else {
            //返回的是失败的标记
            return Promise.reject(new Error(response.message))
        }
    },
}

const mutations = {
	//清除本地数据
    REQ_USER_LOGOUT(state) {
        //帮仓库中相关用户信息清空
        state.token = '';
        state.userInfo = {};
        //本地存储数据清空
        removeToken();
    },
}

const state = {
	token: getToken(),
}

src/utils/token.js

//清除本地存储的token
export const removeToken=()=>{
    localStorage.removeItem("TOKEN");
}

src/コンポーネント/ヘッダー/index.vue

<a class="register" @click="logout">退出登录</a>

//退出登录
async logout() {
      /**
       * 退出登录需要做的事情:
       * 1:需要发请求,通知服务器退出登录【清除一些数据:token】
       * 2:清除项目当中的数据【userInfo、token】
       * 3.成功退出后跳转到/home页
       */
      try {
         //成功
        await this.$store.dispatch('reqLogout');
        this.$router.push("/home")
      } catch (error) {
         //失败
         alert(error.message)
      }
}

注意点1:

質問: ログアウトしてページを更新すると、図に示すようにエラーが報告されます。なぜですか?

ここに画像の説明を挿入

回答: 「Get User Information」アクションをディスパッチするには、ヘッダーでトークンを渡す必要があります。その後、トークンはデフォルトで空の文字列になり、ユーザーがログインしたときにのみトークンに値が割り当てられます。したがって、ホームページが更新され、「Get User Information」アクションがディスパッチされると、トークンが存在しません.値であるため、クエリ インターフェイスでエラーが発生します。

注意点2:

質問: ログアウトについて考えるために何をする必要がありますか?

答え: 3 つのこと:

  1. サーバーにログアウトするように通知するリクエストを送信する必要があります [一部のデータを消去: トークン]
  2. プロジェクト内のデータを消去 [userInfo, token]
  3. 終了後、/home ページにジャンプ

私の他の関連記事へのリンク

1. Vue Shangpinhui mall project-day05 [30. ログインと登録の静的コンポーネント (パブリック イメージ リソースの問題の処理) + 31. 登録済みビジネス + ログイン ビジネス] 2. Vue Shangpinhui mall project-day05 [33. トークン注文 ブランド理解 +
34 .ユーザーログインは、ユーザー情報を取得するためのトークンを運ぶ + 35.ログアウト]
3. Vue Shangpinhui Mall project-day05 [36.ナビゲーションガードの理解]

おすすめ

転載: blog.csdn.net/a924382407/article/details/129907659