如何在 Vue 中使用 axios 检索 JSON Web 令牌?

Posted

技术标签:

【中文标题】如何在 Vue 中使用 axios 检索 JSON Web 令牌?【英文标题】:How to retreive JSON web token with axios in Vue? 【发布时间】:2021-06-27 15:43:55 【问题描述】:

所以我正在尝试为我的第一个 Vue 项目创建一个 CRUD 页面,但我不断收到错误,并且无法找到一个好的解决方案或有效的示例。

当我通过邮递员发布此请求时:

我从我的数据库中获取结果,但是当我尝试从我的 vue 页面执行此操作时,我似乎无法正确处理。我不断收到 401 未经授权的错误,但我认为我确实有一个带有令牌的标头。

我的 vue 页面:

<template>
  <div class="list row">
    <div class="col-md-8">
    </div>
    <div class="col-md-6">
      <h4>Parties List</h4>
      <ul class="list-group">
        <li class="list-group-item"
            :class=" active: index == currentIndex "
            v-for="(party, index) in parties"
            :key="index"
            @click="setActiveParty(party, index)"
        >
           party.name 
        </li>
      </ul>

      <button class="m-3 btn btn-sm btn-danger" @click="removeAllParties">
        Remove All
      </button>
    </div>
    <div class="col-md-6">
      <div v-if="currentParty">
        <h4>Party</h4>
        <div>
          <label><strong>Title:</strong></label>  currentParty.name 
        </div>
        <div>
          <label><strong>Description:</strong></label>  currentParty.description 
        </div>
        <div>
          <label><strong>Is party national:</strong></label>  currentParty.ispartynational ? "Yes" : "No" 
        </div>
        <div>
          <label><strong>partyLeader:</strong></label>  currentParty.partyLeader.name
        </div>

        <a class="badge badge-warning"
           :href="'/parties/' + currentParty.id"
        >
          Edit
        </a>
      </div>
      <div v-else>
        <br />
        <p>Please click on a Party...</p>
      </div>
    </div>
  </div>
</template>


<script>
import PartyDataService from "@/services/PartyDataService";
export default 
  name: "PartiesList",
  data() 
    return 
      parties: [],
      currentParty: null,
      currentIndex: -1,
      name: ""
    ;
  ,
  methods: 
    retrieveParties() 
      PartyDataService.getAll()
          .then(response => 
            this.parties = response.data;
            console.log(response.data);

          )
          .catch(e => 
            console.log(e);
          );
    ,

    refreshList() 
      this.retrieveParties();
      this.currentParty = null;
      this.currentIndex = -1;
    ,

    setActiveParty(party, index) 
      this.currentParty = party;
      this.currentIndex = index;
    ,

    removeAllParties() 
      PartyDataService.deleteAll()
          .then(response => 
            console.log(response.data);
            this.refreshList();
          )
          .catch(e => 
            console.log(e);
          );
    ,
    searchName() 
      PartyDataService.findByName(this.name)
          .then(response => 
            this.tutorials = response.data;
            console.log(response.data);
          )
          .catch(e => 
            console.log(e);
          );
    
  ,

  mounted() 
    this.retrieveParties();
  
;

</script>

<style>
.list 
  text-align: left;
  max-width: 750px;
  margin: auto;

</style>

我的派对数据服务:

import http from "../http-common";

class PartyDataService 
    getAll() 
        return http.get("/parties");

    

    get(id) 
        return http.get(`/parties/$id`);
    

    create(data) 
        return http.post("/parties/", data);
    

    update(id, data) 
        return http.put(`/parties/$id`, data);
    

    delete(id) 
        return http.delete(`/parties/$id`);
    

    deleteAll() 
        return http.delete(`/parties`);
    
    findByName(name)
        return http.get(`/parties/$name`)
    


export default new PartyDataService();

我的 Http-common:

import axios from "axios";

export default axios.create(
    baseURL: "http://localhost:8080/",
    headers: 

         "Content-type": "application/json"
    

);

我尝试在 http-common.js 文件中这样做:

import axios from "axios";

export default axios.create(
    baseURL: "http://localhost:8080/",
    headers: 
         Authorization: 'Bearer ' + localStorage.getItem('Authorization'),
         "Content-type": "application/json"
    

);

但这给了我同样的错误加上一个额外的 cors 错误,当我不包含那行代码时我没有。

我不知道将代码行放在哪里(我认为这将帮助我解决我的问题)。谁能帮我? 提前致谢!

【问题讨论】:

您是否尝试过控制台记录您的 axios req 对象并查看 headers 对象的情况? 您好,我在回答中添加了一些对您有帮助的附加信息。请看一看。 【参考方案1】:

从邮递员请求截图和sn-ps分享的代码来看,Authorization的值似乎不匹配。

在邮递员中:Bearer: your_auth_token

在 axios 标头中:Bearer your_auth_token

Bearer 之后的冒号可能只是这里的问题。

另外,不要直接在axios.create 中设置授权标头。而是创建一个 axios 实例并在请求 obj 上使用 axios 拦截器并在那里设置身份验证令牌。因为您的身份验证令牌可能会过期,并且当您刷新令牌时,axios 不会从本地存储更新新令牌。 axios.create 仅在创建实例时运行一次。因此,它将使用最初添加的令牌。但是,另一方面,每次发出请求时都会调用 Axios 拦截器,因此它会在每次请求之前从本地存储中获取令牌。这可确保您发送有效的令牌而不是陈旧的令牌。希望对您有所帮助。

import axios from 'axios'
import  BASE_URL  from './constants'

const instance = axios.create(
  baseURL: BASE_URL,
)

instance.interceptors.request.use(
    (config) => 
      const token = localStorage.getItem('Authorization')
      if (token) 
         config.headers.Authorization = `Bearer $token`
         config.headers["Content-Type"] = "application/json"
       else 
         // Do something... Usually logout user.
      
      return config
    
)

export default instance

http-common.js 应该类似于上面的内容。

【讨论】:

您有示例链接吗? ***.com/questions/43051291/… 查看 james ace 的答案。这是正确的方式。 所以 james ace 所做的代码应该在我的 http-common 文件中 是的。我已将实现添加到答案中。

以上是关于如何在 Vue 中使用 axios 检索 JSON Web 令牌?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用vue js将数组中的数组检索到表中

如何将 pandas 数据框转换为 json 以在 django 模板中使用

如何使用 Vue-Loader / Webpack 指向外部(动态)资产

使用 Vue 过滤以检索嵌套对象中的特定值

Vue.js 插槽 - 如何在计算属性中检索插槽内容

如何在 Android 的改造请求中传递 JSON 对象并检索 JSON 对象?