gpt4 book ai didi

vue.js - 在vue中处理axios请求返回的认证页面

转载 作者:行者123 更新时间:2023-12-03 06:43:53 26 4
gpt4 key购买 nike

我有一个位于防火墙后面的 vue 应用程序,它控制身份验证。当您第一次访问该应用程序时,您需要进行身份验证,然后您就可以访问该应用程序,直到身份验证过期为止一切正常。从我的应用程序的角度来看,我只知道当我使用 axios 发送 API 请求时用户需要重新进行身份验证,而不是收到预期的有效负载,而是收到 403 错误,我捕获的错误如下:

import axios  from 'axios'
var api_url = '...'

export default new class APICall {
constructor() {
this.axios = axios.create({
headers: {
'Accept': 'application/json',
'Cache-Control': 'no-cache',
'Content-Type': 'application/json',
},
withCredentials: true,
baseURL: api_url
});
}
// send a get request to the API with the attached data
GET(command) {
return this.axios.get(command)
.then((response) => {
if (response && response.status === 200) {
return response.data; // all good
} else {
return response; // should never happen
}
}).catch((err) => {
if (err.message
&& err.message=="Request failed with status code 403"
&& err.response && err.response.data) {
// err.response.data now contains HTML for the authentication page
// and successful authentication on this page resends the
// original axios request, which is in err.response.config
}
})
}
}

在 catch 语句中,err.response.data 是身份验证页面的 HTML,在此页面上成功进行身份验证会自动重新触发原始请求,但我永远不能了解如何使用它来将我想要的有效负载返回到我的应用程序。

虽然从安全角度来看这并不理想,但我可以使用 v-html 标记显示 err.response.data 的内容,但当我这样做时我不能弄清楚如何捕获身份验证页面触发原始请求时返回的有效负载,以便有效负载最终显示在浏览器中。有谁知道如何做到这一点?我尝试将所有内容都包含在 promise 中,但我认为问题是我没有在重新发出的请求周围放置 promise ,因为我无法直接控制它。

我是否需要修改err.response.data中的表单来控制数据的返回方式?我感觉我应该使用拦截器,但不完全确定它们是如何工作的......

编辑

我意识到最干净的方法是在新窗口中打开 error.response.data 中的表单,以便用户可以使用以下内容重新进行身份验证:

var login_window = window.open('about:blank', '_blank');
login_window.document.write(error.response.data)

成功重新验证后,login_window 现在包含原始 axios get 请求的 json。所以我现在的问题是如何检测何时触发身份验证并且 login_window 包含我想要的 json。如 Detect form submission on a page 中所述,从格式化窗口中提取 json 也是有问题的,因为当我“手动”查看 login_window.document.body.innerText 时,我看到了以下形式的文本字符串

JSON
Raw Data
Headers
Save
Copy
Collapse All
Expand All

status \"OK\"
message \"\"
user \"andrew\"

但如果有一种可靠的方法来确定用户何时在 login_window 页面上提交登录表单,然后我可以重新发送请求,我会很高兴。

最佳答案

我会采取不同的方法,这取决于您对 API 的控制:

  • 选项 1:您可以控制(或包装)API
    1. 让 API 返回 401(未经授权 - 意味着需要身份验证)而不是 403(禁止 - 意味着没有适当的访问权限)
    2. 创建一个身份验证 REST API(例如 POST https://apiserver/auth ),该 API 返回新的身份验证 token
    3. 使用 Axios 拦截器:
this.axios.interceptors.response.use(function onResponse(response) {
// Any status code that lie within the range of 2xx cause this function to trigger
// no need to do anything here
return response;
}, async function onResponseError(error) {
// Any status codes that falls outside the range of 2xx cause this function to trigger
if ("response" in error && "config" in error) { // this is an axios error
if (error.response.status !== 401) { // can't handle
return error;
}
this.token = await this.axios.post("auth", credentials);
error.config.headers.authorization = `Bearer ${this.token}`;
return this.axios.request(config);
}
return error; // not an axios error, can't handler
});

这样做的结果是用户根本不会遇到这种情况,一切都照常进行。

  • 选项 2:您无法控制(或包装)API
    1. 使用拦截器:
this.axios.interceptors.response.use(function onResponse(response) {
// Any status code that lie within the range of 2xx cause this function to trigger
// no need to do anything here
return response;
}, async function onResponseError(error) {
// Any status codes that falls outside the range of 2xx cause this function to trigger
if ("response" in error && "config" in error) { // this is an axios error
if (error.response.status !== 403) { // can't handle
return error;
}
if (!verifyLoginHtml(error.response.data)) { // this is not a known login page
return error;
}
const res = await this.axios.post(loginUrl, loginFormData);
return res.data; // this should be the response to the original request (as mentioned above)
}
return error; // not an axios error, can't handler
});

关于vue.js - 在vue中处理axios请求返回的认证页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60327960/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com