CLI — 登录写法
最后更新于:2022-04-02 08:10:08
[TOC]
>[success] # 登录代码案例
~~~
1.用户输入用户名密码 --》 后台返回一个状态 --》 保存这个状态的token --》
输入url --》 判断有没有token --》有就走后台验证token 接口--》没有就让用户登录
2.退出后要跳回登录页
3.下面的案例对安全性不高的需求使用,高安全的建议后台设置cookies
~~~
>[info] ## 在lib文件下的util.js 添加获取和增加cookie的方法
~~~
1.需要npm install js-cookie -- 用来操作cookie
~~~
>[danger] ##### setToken -- 添加一个cookie
~~~
1.当我们从后台获取的token验证的钥匙,可以存到cookies中
~~~
~~~
export const setToken = (token, tokenName = 'token') => {
Cookies.set(tokenName, token)
}
~~~
>[danger] ##### getToken -- 获得cookie中的token
~~~
1.当我们从获取保存在cookie中的token时候
~~~
~~~
export const getToken = (tokenName = 'token') => {
return Cookies.get(tokenName)
}
~~~
>[info] ## 对lib文件下的axios进行改造
~~~
1.和之前代码不同点,这里请求拦截的时候配置了一个请求头,这个请求头
传递token,后台人员获取这个请求头中的token 来判断token是否失效,或
者真假'config.headers['Authorization'] = getToken()'
2.好处是当我们使用其他接口的时候,每次请求自动拼接在请求头中,不用
在每个接口使用的时候都传递token
3.因为要在请求头传递token,所以这里面使用了,在lib文件夹下的util.js,
中的getToken 方法
~~~
>[danger] ##### 改造后的代码
~~~
import axios from 'axios'
import { baseURL } from '@/config'
import { getToken } from '@/lib/util'
class HttpRequest {
constructor (baseUrl = baseURL) {
this.baseUrl = baseUrl
this.queue = {}
}
getInsideConfig () {
const config = {
baseURL: this.baseUrl,
headers: {
//
}
}
return config
}
distroy (url) {
delete this.queue[url]
if (!Object.keys(this.queue).length) {
// Spin.hide()
}
}
interceptors (instance, url) {
instance.interceptors.request.use(config => {
// 添加全局的loading...
if (!Object.keys(this.queue).length) {
// Spin.show()
}
this.queue[url] = true
config.headers['Authorization'] = getToken()
return config
}, error => {
return Promise.reject(error)
})
instance.interceptors.response.use(res => {
this.distroy(url)
const { data } = res
return data
}, error => {
this.distroy(url)
return Promise.reject(error)
})
}
request (options) {
const instance = axios.create()
options = Object.assign(this.getInsideConfig(), options)
this.interceptors(instance, options.url)
return instance(options)
}
}
export default HttpRequest
~~~
>[info] ## 编写api 文件夹下的user.js中文件的登陆接口
~~~
1.我们将有关用户的接口,都维护到user.js 文件件中
~~~
>[danger] ##### 登陆接口
~~~
export const login = ({ userName, password }) => {
return axios.request({
url: '/index/login',
method: 'post',
data: {
userName,
password
}
})
}
~~~
>[info] ## 编写api 文件夹下的user.js中文件的token验证接口
~~~
1.每次访问视图组建时候,需要我们去调用这个接口,也是后台提供一个验
证,登陆是否失效和正确的预留接口
~~~
>[danger] ##### 验证token接口
~~~
export const authorization = () => {
return axios.request({
url: '/users/authorization',
method: 'get'
})
}
~~~
>[info] ## 在store 文件下moudule文件夹下的user.js文件
~~~
1.在vuex 中调用登陆接口,为了让项目更茁壮在store 文件夹下创建了,
一个负责个个模块的module 文件夹,再里面创建了一个user.js 文件专门
保存用户模块的vuex
2.因为登陆是异步请求,因此使用vuex中的actions方法去调用接口
3.下面'login' 方法返回的是一个'Promise'对象,因为请求调用的接口是异步
的,所以我们将这个异步封装到'Promise'在使用的时候可以更加方便
4.commit 是文档中说的载荷也是用来控制mutations一个方法
5.catch抓的不是200 status 会走catch里面
6.登陆成功需要使用我们封装的setToken ,将token存进cookie中
7.'authorization ' token是正确的就给他重新赋值一个cookie
~~~
>[danger] ##### user.js 内容一个是调用登陆接口,一个是验证token接口,一个注销方法
~~~
import { login, authorization } from '@/api/user'
import { setToken } from '@/lib/util'
const state = {
userName: 'Lison'
}
const getters = {
firstLetter: (state) => {
return state.userName.substr(0, 1)
}
}
const mutations = {
SET_USER_NAME (state, params) {
state.userName = params
}
}
const actions = {
updateUserName ({ commit, state, rootState, dispatch }) {
// rootState.appName
},
login ({ commit }, { userName, password }) {
return new Promise((resolve, reject) => {
login({ userName, password }).then(res => {
if (res.code === 200 && res.data.token) {
setToken(res.data.token)
resolve()
} else {
reject(new Error('错误'))
}
}).catch(error => {
reject(error)
})
})
},
authorization ({ commit }, token) {
return new Promise((resolve, reject) => {
authorization().then(res => {
if (parseInt(res.code) === 401) {
reject(new Error('token error'))
} else {
setToken(res.data.token)
resolve()
}
}).catch(error => {
reject(error)
})
})
},
logout () {
setToken('')
}
}
export default {
getters,
state,
mutations,
actions,
modules: {
//
}
}
~~~
>[info] ## 视图组件login.vue中使用
~~~
1....mapActions是快速使用vuex 中actions 里面的方法
2.用户登录成功用'this.$router.push'就跳转到首页
~~~
>[danger] ##### 代码
~~~
~~~
>[info] ## 在router文件下的index.js 做路由拦截
~~~
1.先调用封装的'getToken' 方法判断token是否存在cookie中
2.如果存在调用在'vuex' actions 方法存在的'authorization' 方法,这个方法
需要接受一个参数'token',vuex 中的这个方法实际调用的是一个后台,接口
方法,这个方法用来判断当前token是否正确
3.如果不正确一定要清除当前的cookie中保存的token
~~~
>[danger] ##### 代码
~~~
import Vue from 'vue'
import Router from 'vue-router'
import routes from './router'
import store from '@/store'
import { setTitle, setToken, getToken } from '@/lib/util'
Vue.use(Router)
const router = new Router({
routes
})
const HAS_LOGINED = false
router.beforeEach((to, from, next) => {
to.meta && setTitle(to.meta.title)
// if (to.name !== 'login') {
// if (HAS_LOGINED) next()
// else next({ name: 'login' })
// } else {
// if (HAS_LOGINED) next({ name: 'home' })
// else next()
// }
const token = getToken()
if (token) {
store.dispatch('authorization', token).then(() => {
if (to.name === 'login') next({ name: 'home' })
else next()
}).catch(() => {
setToken('')
next({ name: 'login' })
})
} else {
if (to.name === 'login') next()
else next({ name: 'login' })
}
})
export default router
~~~
';