用户登录

  作者:记性不好的阁主

1、在路由前进行登录状态判断


import router from "./router"
import store from "./store"
import { Message } from 'element-ui'
// 进度条js
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import { getToken } from '@/utils/auth'
// 进度环显示隐藏
NProgress.configure({showSpinner: false})
// 设置免登陆白名单
const whiteList = ['/login', '/auth-redirect', '/bind', '/register']

// 路由前的操作
router.beforeEach((to, from, next) => {
//顶部进度条开始显示加载
NProgress.start()
// 如果cookie中有token
if (getToken()) {
if (to.path === '/login') {
// 如果是/login, 路由到/
next({ path: '/' })
NProgress.done()
} else {
if (store.getters.roles.length === 0) {
// 判断当前用户是否已拉取完user_info信息
store.dispatch('GetInfo').then(res => {
// 拉取user_info
const roles = res.roles
store.dispatch('GenerateRoutes', { roles }).then(accessRoutes => {
// 测试 默认静态页面
// store.dispatch('permission/generateRoutes', { roles }).then(accessRoutes => {
// 根据roles权限生成可访问的路由表
router.addRoutes(accessRoutes) // 动态添加可访问路由表
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
})
})
.catch(err => {
store.dispatch('FedLogOut').then(() => {
Message.error(err)
next({ path: '/' })
})
})
} else {
next()
// 没有动态改变权限的需求可直接next() 删除下方权限判断
// if (hasPermission(store.getters.roles, to.meta.roles)) {
// next()
// } else {
// next({ path: '/401', replace: true, query: { noGoBack: true }})
// }
// 可删
}
}
}else {
//如果没有token
if(whiteList.indexOf(to.path) !== -1){
//如果目标路径在白名单中,则直接进入
next()
}else {
next(`/login?redirect=${to.path}`) //重定向到登录页
// 进度条结束
NProgress.done()
}
}

})
// 进入目标路由后进度条结束
router.afterEach(() => {
NProgress.done()
})


当访问:http://localhost:80时,浏览器的cookie中没有存在token,会重定向到登录页http://localhost:80/login?redirect=/,走代码块:


next(`/login?redirect=${to.path}`) //重定向到登录页
// 进度条结束
NProgress.done()


2、处理登录方法


handleLogin() {
this.$refs.loginForm.validate(valid => {
if (valid) {
this.loading = true;
if (this.loginForm.rememberMe) {
Cookies.set("username", this.loginForm.username, { expires: 30 });
Cookies.set("password", this.loginForm.password, { expires: 30 });
Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 });
} else {
Cookies.remove("username");
Cookies.remove("password");
Cookies.remove('rememberMe');
}
this.$store
.dispatch("Login", this.loginForm)
.then(() => {
this.loading = false;
// 登录后 接收 ?redirect={参数} 赋值给 this.redirect 然后跳转到该路由
this.$router.push({ path: this.redirect || "/" });
})
.catch(() => {
this.loading = false;
this.getCode();
});
}
});
}


由于重定向到http://localhost:80/login?redirect=/,所以this.redirect = "/",登录完成后会重定向到/。


this.$store
.dispatch("Login", this.loginForm)


收集表单信息进行登录,并将token存储到本地cookie


// 登录
Login({ commit }, userInfo) {
const username = userInfo.username.trim()
const password = userInfo.password
const code = userInfo.code
const uuid = userInfo.uuid
return new Promise((resolve, reject) => {
login(username, password, code, uuid).then(res => {
setToken(res.token)
commit('SET_TOKEN', res.token)
resolve()
}).catch(error => {
reject(error)
})
})
}



// 登录方法
export function login(username, password, code, uuid) {
const data = {
username,
password,
code,
uuid
}
return request({
url: '/login',
method: 'post',
params: data
})
}



3、封装请求


import axios from 'axios'
import { Notification, MessageBox } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'

axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
const service = axios.create({
// axios中请求配置有baseURL选项,表示请求URL公共部分
baseURL: process.env.VUE_APP_BASE_API,
// 超时
timeout: 10000
})
// request拦截器
service.interceptors.request.use(
config => {
if (getToken()) {
config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
}
return config
},
error => {
console.log(error)
Promise.reject(error)
}
)

// 响应拦截器
service.interceptors.response.use(res => {
const code = res.data.code
if (code === 401) {
MessageBox.confirm(
'登录状态已过期,您可以继续留在该页面,或者重新登录',
'系统提示',
{
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning'
}
).then(() => {
store.dispatch('LogOut').then(() => {
location.reload() // 为了重新实例化vue-router对象 避免bug
})
})
} else if (code !== 200) {
Notification.error({
title: res.data.msg
})
return Promise.reject('error')
} else {
return res.data
}
},
error => {
console.log('err' + error)
Message({
message: error.message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
)

export default service



baseURL: process.env.VUE_APP_BASE_API,

读取 .env.development文件

# 开发环境配置
ENV = 'development'

# 若依管理系统/开发环境
VUE_APP_BASE_API = '/dev-api'

# 路由懒加载
VUE_CLI_BABEL_TRANSPILE_MODULES = true


请求拦截器

// request拦截器
service.interceptors.request.use(
config => {
if (getToken()) {
config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
}
return config
},
error => {
console.log(error)
Promise.reject(error)
}
)


如果本地cookie中有token,那么每次请求时携带上请求头:Authorization

登录接口无需token,当登录成功后将生成对应的token返回给前端

/**
* 登录方法
*
* @param username 用户名
* @param password 密码
* @param captcha 验证码
* @param uuid 唯一标识
* @return 结果
*/
@PostMapping("/login")
public AjaxResult login(String username, String password, String code, String uuid)
{
AjaxResult ajax = AjaxResult.success();
// 生成令牌
String token = loginService.login(username, password, code, uuid);
ajax.put(Constants.TOKEN, token);
return ajax;
}



/**
* 获取请求token
*
* @param request
* @return token
*/
private String getToken(HttpServletRequest request)
{
String token = request.getHeader(header);
if (StringUtils.isNotEmpty(token) && token.startsWith(Constants.TOKEN_PREFIX))
{
token = token.replace(Constants.TOKEN_PREFIX, "");
}
return token;
}


// 令牌自定义标识
@Value("${token.header}")
private String header;


# token配置
token:
# 令牌自定义标识
header: Authorization


Constants.TOKEN_PREFIX

/**
* 令牌前缀
*/
public static final String TOKEN_PREFIX = "Bearer ";




相关推荐

评论 抢沙发

表情

分类选择