登录:
登录最基本的动作为:成功后跳转到首页。login 页面中,如果后台验证成功,要动态改变路由到首页;验证的动作,调用的是store当中的“Login”方法, 我们把“Login”方法放到store当中,为什么呢?因为我们要保存token到store当中,同时,把这个token也存储到cookie当中一份。
login页面当中,主要作用:
- 发起登录
- 验证成功后,跳转页面
- 把用户名等信息存储到localstorage
store当中,异步验证成功后:
- 把token存储到store
- token存到cookee当中(这个似乎也可在页面当中进行)
登录:当用户填写完账号和密码后向服务端验证是否正确,验证通过之后,服务端会返回一个token,拿到token之后(我会将这个token存贮到cookie中,保证刷新页面后能记住用户登录状态)
click事件触发登录操作(login.vue页面当中):
handleLogin() {
// 这里需要调用login的接口
if (this.loginForm.year === '' || this.loginForm.admdivcode === '') {
this.$message.error('请选择年度和区划!')
} else {
this.$refs.loginForm.validate(valid => {
if (valid) {
this.loading = true
this.$store.dispatch('Login', this.loginForm).then(() => {
//动态路由
this.loading = false
this.$router.push({ path: this.redirect || '/' })
//localStorage中保存用户名、年度等信息
var { username, year, admdivcode } = this.loginForm
localStorage.setItem('year', year)
localStorage.setItem('admdivcode', admdivcode)
localStorage.setItem('username', username)
console.log('保存了本地登陆信息。')
isShow().then(res => {
console.log('rrrr', res)
res.data.paramvalue && this.$store.commit('SET_isShow', res.data.paramvalue)
})
}).catch(() => {
this.loading = false
})
} else {
console.log('error submit!!')
return false
}
})
}
}
action:(user.js中):
Login({ commit }, userInfo) {
console.log('收到的用户信息为:', userInfo)
const username = userInfo.username.trim()
return new Promise((resolve, reject) => {
login(username, userInfo.password, userInfo.year, userInfo.admdivcode).then(response => {
const data = response.data
setToken(data.token)
commit('SET_TOKEN', data.token)
resolve()
}).catch(error => {
reject(error)
})
})
},
登录成功后,服务端会返回一个 token(该token的是一个能唯一标示用户身份的一个key),之后我们将token存储在本地cookie之中,这样下次打开页面或者刷新页面的时候能记住用户 的登录状态,不用再去登录页面重新登录了。token我们在state中,也存储了一份。
commit('SET_TOKEN', data.token),我们把token在store当中也存了一份,我们request拦截器中,用到了token。每个请求,都会加上token.
// request拦截器
service.interceptors.request.use(
config => {
if (store.getters.token) {
config.headers['X-Token'] = getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
}
// showFullScreenLoading()
startLoading()
return config
},
error => {
// Do something with request error
console.log(error) // for debug
Promise.reject(error)
}
)
localStorage中没有存token信息 。token是登陆的时候存在cookie中的 ,登陆后又发送了获取用户信息的请求,将有用的用户信息存到了localStorage中方便下次登陆使用。
这里的year这些信息,是用户选择的,只在login页面有,如果想在action中存,取值很麻烦,不划算。
ps:这里有个问题,什么 情况数据存储咋localstorage,什么时候存在vuex,参考文档:vuex存储和本地存储(localstorage、sessionstorage)的区别
ps2:服务端用shiro框架:
@PostMapping("/login")
public R login(@RequestBody() BasPersonnel basPersonnel) {
HashMap<Object, Object> map = new HashMap<>();
Subject subject = SecurityUtils.getSubject();
try {
PersonnelPasswordToken token = new PersonnelPasswordToken(basPersonnel);
subject.login(token);
} catch (Exception e) {
return R.error(e.getCause().getMessage());
}
map.put("token", subject.getSession().getId());
basPersonnelService.clearResourceCache(UserUtil.getBasPersonnel().getGuid());
...//其他附加业务处理
return R.ok(map);
}
其中,clearResourceCache方法,清除了这个用户的相关菜单等信息?:
@Override
@Caching(evict = {
@CacheEvict(value = CacheConfig.BasPersonneUserToResource, key = "#p0"),
@CacheEvict(value = CacheConfig.userShortcut, key = "#p0")
})
public void clearResourceCache(String userid) {
log.info("clear Resource Cache");
}