使用token登录完整流程前端加后端

使用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,返回登录页面。

  • 3
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值