Vue Shangpinhui Mall Project-day05 [33. Token token understanding + 34. User login and carry token to obtain user information + 35. Log out]

insert image description here

33. token token understanding

【Token: string, the identity certificate issued by the server to the user】
Example: ancient war, soldier symbol

34. User login carries token to obtain user information

Show effect before login:

insert image description here

Display effect after successful login:

insert image description here

Modify the code:

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/components/Header/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");
};

Note 1:

Question: Where to dispatch the "get user information" action?

Answer: Dispatched when the Home component is suspended, because it will jump to the Home component after successful login.

Note 2:

Problem: After successful login, the display in the upper left corner of the Home component should be different.

Show effect before login:

insert image description here

Display effect after successful login:

insert image description here

Answer: give/

Add v-if and v-else to the label to control the display and hiding.

Note 3: To obtain user information, you need to pass the token in the header, otherwise the backend will not know who it is. Therefore, token information needs to be added to the request header in the src/api/axios.js file.

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

Note 4:

Question: After refreshing, the information displayed in the upper left corner of the user who has just logged in is gone. Why? The specific effect is shown in the figure:

insert image description here

Answer: Because the information stored in vuex is non-persistent, it is necessary to use persistent storage technology to store token information.

Note 5:

Question: Refreshing in the Home component can also display user information, but jumping to other components such as [Detail Component|Search Component] finds that it is gone? why?

Answer: Because dispatching the "get user information" action is only triggered when the Home component is suspended.

Hypothetical solution 1: If each component copies and distributes the "get user information" action, the effect can be achieved, but it is too troublesome for you to write each component, and if one is missing, there will be a display problem;

Hypothesis 2: What if the action is dispatched in the parent component APP component? The answer is no, because the APP component will only be loaded once, and the user information will be displayed after refreshing after login, but it will not be displayed if it is not refreshed. Obviously, this solution is not correct.

The final solution: Use the "navigation guard-global guard" to solve the problem, and delete the "get user information" action dispatched in the Home component, and put everything in the "navigation guard" to solve. For details, please refer to knowledge point "36. Navigation guard understanding"

Note 6:

Problem: The user is already logged in and should no longer be able to return to the login page.

Answer: The final solution: use "navigation guard-global guard" to solve the problem. For details, please refer to knowledge point "36. Navigation guard understanding"

35. Log out

Modify the code:

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/components/Header/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)
      }
}

Note 1:

Question: After logging out and refreshing the page, an error is reported as shown in the figure, why?

insert image description here

Answer: To dispatch the "Get User Information" action, you need to pass in the token in the header, and then the token defaults to an empty string and the token will only be assigned a value when the user logs in. Therefore, when the Home page is refreshed and the "Get User Information" action is dispatched, the token does not exist. value, so the query interface results in an error.

Note 2:

Question: What do you need to do to think about logging out?

Answer: 3 things:

  1. Need to send a request to notify the server to log out [clear some data: token]
  2. Clear the data in the project [userInfo, token]
  3. Jump to /home page after successful exit

Links to my other related articles

1. Vue Shangpinhui mall project-day05 [30. Login and registration static components (handling public image resource issues) + 31. Registered business + login business] 2.
Vue Shangpinhui mall project-day05 [33. token order Brand understanding + 34. User login carries token to obtain user information + 35. Logout]
3. Vue Shangpinhui Mall project-day05 [36. Navigation guard understanding]

Guess you like

Origin blog.csdn.net/a924382407/article/details/129907659