33.token令牌理解
【令牌:字符串,服务器下发给用户的身份凭证】
举例子:古代大战,兵符
34.用户登录携带token获取用户信息
登陆之前展示效果:
登陆成功后展示效果:
修改代码:
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");
};
注意点1:
问题:哪里派发“获取用户信息”action呢?
答案:在Home组件挂在完毕时派发,因为登录成功后会跳转到Home组件中。
注意点2:
问题:登陆成功后,在Home组件中左上角展示应该有所不同。
登陆之前展示效果:
登陆成功后展示效果:
答案:给/
标签添加v-if和v-else,进行控制显隐。
注意点3:获取用户信息需要在header中传递token,否则后端不认识是谁。因此需要在src/api/axios.js文件中在请求头header中补充token信息。
//需要携带token带给服务器
if(store.state.user.token){
//请求头添加一个字段(userTempId):和后台老师商量好了
config.headers.token = store.state.user.token;
}
注意点4:
问题:一刷新,刚刚已经登陆过的用户左上角展示信息又没了,为啥?具体效果如图:
答案:因为vuex中存储的信息是非持久化的,所以需要用到持久化存储技术去存储token信息。
注意点5:
问题:在Home组件中刷新也能显示用户信息了,但是跳转到其他组件比如【详情组件|搜索组件】中发现又没了?为啥?
答案:因为派发“获取用户信息”action只放在了Home组件挂在完毕时触发。
假设方案1:那如果每个组件都拷贝一份派发“获取用户信息”action呢,是可以达到效果,但你每个组件都写太费事且万一遗漏一个就出显示问题了;
假设方案2:那如果放在父组件APP组件中派发action呢?答案也不行,因为APP组件只会加载一次,登录后刷新才会展示用户信息,但不刷新还是不显示,明显该方案也不对。
最终的方案:使用“导航守卫-全局守卫”解决问题,并把Home组件中派发“获取用户信息”action删除,一切都放在“导航守卫”中解决。详情请看知识点“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/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)
}
}
注意点1:
问题:退出登录后刷新页面,报错如图,为啥?
答案:派发"获取用户信息"action需要header中传入token,然后token默认为空串且只有在用户登录下才会给token赋值,所以当刷新Home页派发"获取用户信息"action时由于token没有值,所以查询接口结果报错。
注意点2:
问题:思考退出登录都需要干什么?
答案:3件事情:
- 需要发请求,通知服务器退出登录【清除一些数据:token】
- 清除项目当中的数据【userInfo、token】
- 成功退出后跳转到/home页
本人其他相关文章链接
1.vue尚品汇商城项目-day05【30.登录与注册静态组件(处理公共图片资源问题)+31.注册的业务+登录业务】
2.vue尚品汇商城项目-day05【33.token令牌理解+34.用户登录携带token获取用户信息+35.退出登录】
3.vue尚品汇商城项目-day05【36.导航守卫理解】