使用token登录完整流程前端加后端
完整代码请访问:https://github.com/ziheng42/token-.git效果如下:可以看出在没有登陆之前,点击路由跳转是没有作用的。在点击登录之后,便可以进行路由跳转,相应的本地存储空间,也是有了token的存在。在清除掉token后,路由跳转也是没有了作用。下边我们来一步一步实现。首先搭建项目框架,前端使用vue3,后端使用express。前端项目搭建不再赘述,这里主要说明后
使用token登录完整流程前端加后端
完整代码请访问:https://github.com/ziheng42/token-.git
效果如下:
可以看出在没有登陆之前,点击路由跳转是没有作用的。在点击登录之后,便可以进行路由跳转,相应的本地存储空间,也是有了token的存在。在清除掉token后,路由跳转也是没有了作用。
下边我们来一步一步实现。
首先搭建项目框架,前端使用vue3,后端使用express。前端项目搭建不再赘述,这里主要说明后端的搭建
- npm init -y
- npm install –save express
- npm install cors
- npm install jsonwebtoken –save
- npm install nodemon
安装好这些依赖后你的项目目录应该是这样的
新建app.js,复制以下代码
const express = require('express')
const cors = require('cors') //处理跨域
const app = express()
app.use(cors({
//当axios配置了withCredentials, 需要设置具体的地址,以及credentials
origin:"http://localhost:8080",
credentials: true
}))
//处理数据中间件
app.use(express.json())
app.use(express.urlencoded({extended: true}))
//路由监听
app.use("/", require('./router/index'))
//端口监听:开放端口
app.listen(3000, () => {
console.log('服务器开启:localhost:3000');
})
新建router文件夹。
在router文件夹下的index文件中写入
const express = require('express')
const router = express.Router()
router.use('/app',require('./app/index'))
module.exports = router
在router —-app ——index.js
const express = require('express')
const router = express.Router()
router.post('/login', (req, res) => {
res.send({
token:'子恒真帅'
})
})
module.exports = router
现在后端就搭建完成了。
使用nodemon app.js启动项目,在浏览器地址栏输入localhost:3000,可以看到你写的内容就成功了。
如果是从github上下载我的代码。可以直接来到这一步。
现在开始配置axios
- npm install axios
在项目目录src文件夹下建立如下文件夹
axios放置axios配置,index.js文件夹中放置接口函数,
import axios from 'axios'
import router from '../router/index'
let baseUrl
// 判断开发环境(一般用于本地代理)
if (process.env.NODE_ENV === 'development') { // 开发环境
baseUrl = 'http://localhost:3000'
} else { // 编译环境
if (process.env.type === 'test') { // 测试环境
baseUrl = 'http://sw.apitest.com'
} else { // 正式环境
baseUrl = 'http://sw.api.com'
}
}
axios.defaults.timeout = 4000 //请求超时
axios.defaults.baseURL = baseUrl //全局地址
axios.defaults.responseType = 'json' //接收数据格式。默认json格式
axios.defaults.withCredentials = true //是否携带cookie
export default axios
新建接口函数,用于生成token
import axios from './axios'
//请求token接口
export const app = (datas)=>{
return axios({
url:'/app/login',
method:'post',
data:datas
})
}
//检验token接口。
export const login = (datas)=>{
return axios({
url:'/app/token',
method:'post',
data:datas
})
}
在login页面中调用。
<template>
<div class="main">
<div>
{{denglu}}
</div>
<div class="btn" @click="Login">登录</div>
</div>
</template>
<script setup>
import { app } from "@/axios/index";
import { ref} from "vue";
import {useRoute, useRouter} from 'vue-router'
const router = useRouter()
const denglu = ref('请登录')
const Login = () => {
app({
name: 'ziheng'
}).then((res) => {
let { token } = res.data
localStorage.setItem('token', token) //放在localStorage中。浏览器也是电脑上的一个程序,他就是一个文件夹,localStorage也在其中,只要你不删除历史记录,那么他就一直存在,一个域对应一个。
router.push('/')
})
}
</script>
<style lang="less" scoped>
.main{
margin: 20px;
display: flex;
.btn{
margin-left: 20px;
color: rgb(39, 228, 199);
cursor: pointer;
}
}
</style>
在后台中响应请求。
const express = require('express')
const router = express.Router()
const jwt = require('jsonwebtoken') //引入jsonwebtoken
const key = 'zheshiyitiaoshenqidetianlu' //定义jsonwebtoken的加密字符串,这个是随便定的,
//生成token
router.post('/login', (req, res) => {
let {name} = req.body //通过req.body响应请求
let token = jwt.sign({
name:name
},
key,
{
expiresIn:'7d'
})
//通过res.send给前端返回数据。
res.send({
token:token
})
})
//检验token正确是否
router.post('/token',(req, res)=>{
let token = req.headers.authorization
token = token.split(' ')[1]
console.log(123);
try {
const Token = jwt.verify(token, key)
console.log(Token);
//返回前端
res.send({
code:0,
msg:'登录成功'
})
} catch (error) {
console.log(error);
res.send(401)
}
})
module.exports = router
然后在路由守卫中进行验证token是否存在。
import { createRouter, createWebHashHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
const routes = [
{
path: '/',
name: 'home',
component: HomeView
},
{
path: '/about',
name: 'about',
meta:{requiresAuth:true},
component: () => import('../views/AboutView.vue')
},
{
path: '/login',
name: 'Login',
component: () => import('../views/login.vue')
}
]
const router = createRouter({
history: createWebHashHistory(),
routes
})
router.beforeEach((to,from,next) =>{
let token = localStorage.getItem('token')
if(to.name!=='Login' && !token)next({name:'Login'})
else next()
})
export default router
在这里其实已经实现了刚开始的动态图效果,但是这里其实有一个问题,那就是没有验证token是否正确或者是token是否过期。
在这里可以看到,我先是删除token,然后手动新建token,可以看出我新建的token明显是错误的,但是他竟然可以跳转路由。
路由守卫中其实只是验证了token是否存在,那么该怎么办呢
在axios中为我们提供了请求拦截器,在axios配置文件夹中写入以下代码
//请求拦截,为所有的请求添加请求头,
axios.interceptors.request.use(
(config) => {
const token = localStorage.getItem('token')
if (token) config.headers.Authorization = `Bearer ${token}`//这里加Bearer是现在行业的一个规范,出现这个则表明后边的字符串是token。
return config
},
(error) => {
return Promise.reject(error)
}
)
//响应拦截, 处理响应的数据
axios.interceptors.response.use(
(response) => response,
//失败的情况。401代表验证未通过。
(error) => {
let { status } = error.response
if (status === 401) {
router.replace({ name: 'Login' })
localStorage.clear('token')
}
}
)
一般来说进入其他页面都是有着请求发生。在这里我使用点击事件模拟。
如下:
这里可以看出,我首先登录拿到正确的token,跳转,点击事件进行验证,均没有问题,然后我修改token,让其错误,然后点击事件,通过后端验证时没有通过,返回401,然后清除token,返回登录页面。
更多推荐
所有评论(0)