国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

node后端+vue前端實現(xiàn)接口請求時攜帶authorization驗證

這篇具有很好參考價值的文章主要介紹了node后端+vue前端實現(xiàn)接口請求時攜帶authorization驗證。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

node后端+vue前端實現(xiàn)接口請求時攜帶authorization驗證

我們在寫web項目時,后端寫好接口,前端想要調(diào)用后端接口時,除了登錄注冊頁面,所有的請求都需要攜帶authorization,這樣是為了避免隨意通過接口調(diào)取數(shù)據(jù)的現(xiàn)象發(fā)生。這是寫web項目時最基礎(chǔ)的點,但是也挺麻煩的,涉及前后端好幾個地方的編碼,經(jīng)常忘記怎么寫的,現(xiàn)在記錄一下。

總體流程如下:

  1. 后端使用中間件開啟接口請求驗證,除登錄/注冊外所有接口的請求都需要攜帶驗證參數(shù)才能正確發(fā)起請求
  2. 前端登錄時,存儲驗證消息,也就是token
  3. 請求攔截器中設(shè)置請求頭,寫入authorization

大體就這么幾個步驟,下面細化

一、后端開啟接口請求驗證

我是用node寫的后端,請求驗證寫在后端入口程序app.js中,完整代碼如下:

const express = require("express");
const cors = require("cors");
const bodyParser = require("body-parser");
const multer = require("multer");
const upload = multer({ dest: "./public/upload" });
const morgan = require("morgan");
const fs = require("fs");

const app = express();

// 創(chuàng)建一個寫入流,將日志寫入access.log文件
const accessLogStream = fs.createWriteStream("./access.log", { flags: "a" });

// 使用Morgan中間件,將日志寫入控制臺和文件
app.use(morgan("combined", { stream: accessLogStream }));

app.use(cors());

app.use(express.urlencoded({ extended: false }));
app.use(bodyParser.json());

// 托管靜態(tài)文件
app.use(upload.any());
app.use(express.static("./public"));

// 處理錯誤的中間件
app.use((req, res, next) => {
  res.cc = (err, status = 1) => {
    res.send({
      status,
      message: err instanceof Error ? err.message : err,
    });
  };
  next();
});

const jwtconfig = require("./jwt_config/index");
const { expressjwt: jwt } = require("express-jwt");
app.use(
  jwt({
    secret: jwtconfig.jwtSecretKey,
    algorithms: ["HS256"],
  }).unless({
    path: [/^\/api\/user\/.*$/],
  })
);

const userManagerRouter = require("./router/user");
app.use("/api/user", userManagerRouter);

const userInfoManageRouter = require("./router/userinfo");
app.use("/api/userinfo", userInfoManageRouter);

const settingRouter = require("./router/setting");
app.use("/api/setting", settingRouter);

const productRouter = require("./router/product");
app.use("/api/product", productRouter);

const messageRouter = require("./router/message");
app.use("/api/message", messageRouter);

const filesRouter = require("./router/files");
app.use("/api/files", filesRouter);

const logRouter = require("./router/log");
app.use("/api/log", logRouter);

const overviewRouter = require('./router/overview')
app.use('/api/overview', overviewRouter)

// 用戶消息讀取情況
const dmMsgRouter = require('./router/department_msg')
app.use('/api/dm', dmMsgRouter)

// 對不符合joi規(guī)則的情況進行報錯
// app.use((err, req, res, next) => {
//   if (err instanceof Joi.ValidationError) return res.cc(err.details[0].message);
//   else res.cc(err);
// });

app.listen(3088, () => {
  console.log("api server running at http://127.0.0.1:3088");
});

這個程序太長,相關(guān)的代碼如下:

const jwtconfig = require("./jwt_config/index");
const { expressjwt: jwt } = require("express-jwt");
app.use(
  jwt({
    secret: jwtconfig.jwtSecretKey,
    algorithms: ["HS256"],
  }).unless({
    path: [/^\/api\/user\/.*$/],
  })
);

其實這個寫法相對來說是固定的,首先,導入自己寫好的jwt驗證規(guī)則(也叫秘鑰),其實就是一個jwtSecretKey,./jwt_config目錄下的index.js文件如下:

module.exports = {
    jwtSecretKey: 'xxx'  // 改成自己的秘鑰
}

然后導入express-jwt,接下來就是使用中間件來設(shè)定接口路由規(guī)則了,unless方法里面寫的是排除的接口地址,是用正則表達式來排除的,/^\/api\/user\/.*$/這個正則表達式的意思是排除所有以/api/user/開頭的接口

可以看上面的完整代碼,app.use("/api/user", userManagerRouter);這里以/api/user/開頭的接口都是給用戶登錄和注冊相關(guān)的接口

后端按這個思路寫就行了

二、登錄存儲token

這里有兩種存儲方式,一種是把token存儲在localstorage中,另外一種是存儲在全局數(shù)據(jù)管理工具中(也就是vuex或者pinia中),這里設(shè)計前后端聯(lián)調(diào)

1、后端寫登錄接口,向前端傳遞token

先看看我的完整的登錄接口處理函數(shù)

exports.login = (req, res) => {
  //   res.send("login");
  const userInfo = req.body;
  const sql = "select * from users where account = ?";
  db.query(sql, userInfo.account, (err, results) => {
    if (err) return res.cc(err);
    if (results.length !== 1) return res.cc("用戶不存在");
    const compareResult = bcrypt.compareSync(
      userInfo.password,
      results[0].password
    );
    if (!compareResult) return res.cc("密碼錯誤");
    // 判斷賬號是否凍結(jié)
    if (results[0].status == 1) return res.cc("賬號被凍結(jié)");
    const user = {
      ...results[0],
      password: "",
      imageUrl: "",
      create_time: "",
      update_time: "",
    };
    const tokenStr = jwt.sign(user, jwt_config.jwtSecretKey, {
      expiresIn: "10h",
    });
    res.send({
        status: 0,
        results: results[0],
        message: '登錄成功',
        token: "Bearer " + tokenStr
    })
  });
};

相關(guān)的代碼如下:

const tokenStr = jwt.sign(user, jwt_config.jwtSecretKey, {
      expiresIn: "10h",
});
res.send({
    status: 0,
    results: results[0],
    message: '登錄成功',
    token: "Bearer " + tokenStr
})

這里其實很簡單,就是后端通過秘鑰生成一個有效期為10小時的token,這里的秘鑰也是上面提到的,然后向前端發(fā)送這個token

2、前端登錄時,存儲token

我用的vue3,數(shù)據(jù)存儲在pinia中,看看我的前端登錄代碼

import { useUserStore } from '@/stores/user'
const userStore = useUserStore()

const loginCB = async () => {
    const { account, password } = form.value
    const data = { account, password }
    loginFormRef.value.validate(async valid => {
        if (valid) {
            try {
                await userStore.getUserInfo(data)
                // console.log(userStore.userInfo)
                if (!userStore.userInfo.token) return ElMessage.error('用戶名或密碼錯誤')
                // console.log(userStore.vue3ManageUserInfo)
                router.push('/')
                // console.log(results)
            } catch (error) {
                ElMessage.error('用戶名或密碼錯誤')
                console.log(error)
            }
        } else {
            ElMessage.error('沒通過校驗')
        }
    })
}

上面這段代碼不是完整的,loginCB是登錄按鈕的回調(diào)函數(shù),從回調(diào)中看到,其實我的登錄是寫在pinia的getUserInfo方法中的,繼續(xù)看看這個store中的寫法

import { ref } from "vue";
import { defineStore } from "pinia";
import { loginAPI } from "@/apis/user";
import { getUserInfoAPI } from "@/apis/userinfo";
import { loginLogAPI } from "@/apis/log";

export const useUserStore = defineStore(
  "user",
  () => {
    const userInfo = ref({});
    const getUserInfo = async (data) => {
      const res = await loginAPI(data);
      // console.log(res);
      userInfo.value = {
        account: res.results.account,
        token: res.token,
        avatar: res.results.image_url,
        id: res.results.id,
        name: res.results.name,
        sex: res.results.sex,
        email: res.results.email,
        department: res.results.department,
        identity: res.results.identity
      };
      // 登錄日志
      await loginLogAPI({
        account: res.results.account,
        name: res.results.name,
        email: res.results.email,
      });
      // console.log(userInfo.value)
    };
    // 修改頭像
    const changeAvatar = (url) => {
      userInfo.avatar = url;
    };
    // 修改姓名
    const changeName = (name) => {
      userInfo.name = name;
    };
    //   解決刷新頁面丟失store信息的問題
    const clearUserInfo = () => {
      userInfo.value = {};
    };
    return {
      userInfo,
      getUserInfo,
      clearUserInfo,
      changeAvatar,
      changeName,
    };
  },
  {
    persist: true,
  }
);

pinia中我用的是組合式api的寫法,其實也是比較流行的寫法,邏輯和語法都比較清楚

可以看到,我定義了一個userInfo的state,登錄需要調(diào)用loginAPI,這個接口對應(yīng)后端的login函數(shù),請求到數(shù)據(jù)后,將接口返回的token寫入到userInfo.token中,這樣,全局數(shù)據(jù)管理store中就存儲了一個包含token的名為userInfo的state(真的繞。。。)

注意,組合式api需要將state return出去

  {
    persist: true,
  }

上面這個是持久化存儲,我在“vue3+pinia用戶信息持久緩存(token)的問題”這篇博客中有記錄,目的是將userInfo存儲到localstorage中

這樣,登錄時要做的工作就做完了

三、請求攔截器中攜帶token

使用axios發(fā)起接口請求,對axios進行二次封裝,封裝代碼如下:

import axios from "axios";
import { ElMessage } from "element-plus";
import { useUserStore } from "@/stores/user";

// 創(chuàng)建axios實例
const http = axios.create({
  baseURL: "http://127.0.0.1:xxxx/api/", // 改成自己的端口
  timeout: 5000,
});

// axios請求攔截器
http.interceptors.request.use(
  (config) => {
    const userStore = useUserStore();
    const token = userStore.userInfo.token;
    if (token) {
      config.headers.Authorization = token;
    }
    return config;
  },
  (e) => Promise.reject(e)
);

// axios響應(yīng)式攔截器
http.interceptors.response.use(
  (res) => res.data,
  (e) => {
    ElMessage.warning("接口響應(yīng)出錯");
    console.log(e);
    return Promise.reject(e);
  }
);

export default http;

注意看請求攔截器中的代碼,用到了剛剛上面提到的pinia中的userInfo這個state,首先獲取userInfo中的token,判斷是否存在token,存在的話,就把它寫到請求頭中去,關(guān)鍵的代碼就是下面這行:

config.headers.Authorization = token;

這樣,每次向后端發(fā)起數(shù)據(jù)請求的時候,都會攜帶這個token了(除了登錄和注冊,因為不存在),后端的中間件也能通過驗證了文章來源地址http://www.zghlxwxcb.cn/news/detail-782823.html

到了這里,關(guān)于node后端+vue前端實現(xiàn)接口請求時攜帶authorization驗證的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • java通過httpclient攜帶請求頭參數(shù)獲取第三方文件流接口并實現(xiàn)實現(xiàn)文件下載

    創(chuàng)建httpclient 請求,并在header攜帶指定key,也可根據(jù)實際需要攜帶token等信息。獲取第三方接口返回的文件輸入流并寫到本地response中,實現(xiàn)返回文件流,前端通過js的a標簽進行下載。 代碼如下: 前端js代碼

    2024年02月16日
    瀏覽(29)
  • json-server Node.js 服務(wù),前端模擬后端提供json接口服務(wù)

    json-server Node.js 服務(wù),前端模擬后端提供json接口服務(wù)

    json-server Node.js 服務(wù),前端模擬后端提供json接口服務(wù) 背景: ? ?前后端分離的項目,如果前端寫頁面的話,必須的后端提供接口文件,作為前端等待時間太久,不便于開發(fā)進行,如果前端寫的過程中自己搭建一個簡要的后端的json服務(wù)接口,就是可以快速進行開發(fā)事項的進行,

    2024年02月16日
    瀏覽(24)
  • SpringBoot+Vue 后端輸出加密,前端請求統(tǒng)一解密

    針對客戶對數(shù)據(jù)交互過程中的加密要求,防止直接的數(shù)據(jù)爬取,對前后端數(shù)據(jù)請求時的返回數(shù)據(jù)進行數(shù)據(jù)的加密。實用性嘛,也就那樣了,代碼可直接適配Ruoyi SpringBoot+vue項目,具體加密方式和處理僅供參考! 前端 request.js des.js 后端java

    2024年02月09日
    瀏覽(29)
  • 前端vue和node后端項目部署到云服務(wù)器(詳解)

    前端vue和node后端項目部署到云服務(wù)器(詳解)

    前言:我是一名大三在校生,選修的專業(yè)是軟件工程,然后主要學前端方向,作為一個前端程員,自己也想有自己的網(wǎng)站,然后被大家瀏覽,我覺得這是對自己能力的肯定,也是自我提升的一種方法,所以我學習了nodejs,利用nodejs作為項目的后端,然后結(jié)合前端最流行的框架

    2024年02月03日
    瀏覽(24)
  • 前端發(fā)送請求獲取后端文件,并且前端實現(xiàn)下載文件功能

    前端發(fā)送請求獲取后端文件,并且前端實現(xiàn)下載文件功能

    最近遇到一個需求,就是前端發(fā)送post請求獲取后端的excel文件,并且前端實現(xiàn)下載導出到本地的功能。 前端頁面就長上面那樣,一個批量導出功能,用戶勾選之后,前端通過接口把id和其他的參數(shù)傳給后端,接口調(diào)用方法這里需要注意的是,這里必須設(shè)置responseType: ‘blob’

    2024年02月09日
    瀏覽(32)
  • 百度語音識別(語音轉(zhuǎn)文字)vue版本 前端(后端需要做個請求轉(zhuǎn)發(fā)即可)

    百度語音識別(語音轉(zhuǎn)文字)vue版本 前端(后端需要做個請求轉(zhuǎn)發(fā)即可)

    這個項目需要用到語音識別,最后選擇的是百度語音識別。原因第一是項目中用到的地方不大,屬于微型和小型功能點,第二就是屬于臨時增加的需求,沒有太多的時間去開發(fā),第三就是后端對于自主開發(fā)語音識別覺得較為困難,浪費時間。 加載語音識別的文件 下載recorde

    2024年02月12日
    瀏覽(20)
  • 前端為什么發(fā)請求沒有攜帶cookie?

    前端為什么發(fā)請求沒有攜帶cookie?

    在前端發(fā)送請求時,如果想要攜帶 cookie,通常只能攜帶存儲在與請求域名相同路徑的 cookie。這是由瀏覽器的同源策略所決定的。 同源策略要求請求的域名、協(xié)議和端口都必須一致,否則瀏覽器會限制跨域請求的權(quán)限。當瀏覽器發(fā)送跨域請求時,默認情況下不會自動攜帶 co

    2024年02月06日
    瀏覽(26)
  • vue2前端使用axios發(fā)起post請求,后端(springboot)拿不到值解決辦法

    vue2前端使用axios發(fā)起post請求,后端(springboot)拿不到值解決辦法

    axios封裝-我常用的請求頭參數(shù)? application/json; charset=utf-8 頁面登錄請求-post 網(wǎng)絡(luò)請求正常傳入?yún)?shù) 后端代碼,查看控制臺發(fā)現(xiàn)都為null,沒取到值。 1.嘗試將前端post請求改成get,其他都不用變 發(fā)現(xiàn)正常取到值,打印輸出正常。前端頁面正常跳轉(zhuǎn)。 2.后端設(shè)置為post請求,前端a

    2024年02月02日
    瀏覽(22)
  • 前端訪問接口 自動攜帶Cookie (axios)

    在跨域請求中,瀏覽器默認情況下不會自動攜帶跨域請求的 cookie。這是由于瀏覽器的同源策略(Same-Origin Policy)所導致的安全性限制。然而,可以通過設(shè)置一些選項來允許瀏覽器發(fā)送跨域請求時攜帶 cookie。 在 Axios 中,你可以通過在請求配置中設(shè)置 withCredentials 選項為 true 來

    2024年04月12日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包