我想api发送otp,但当default_2fa是移动或电子邮件。写这段代码,但响应是空的,即使状态码是200,我做了一些测试otpcall外的if语句和响应工作良好
const login = (values) => {
let payload = {
"input": values.phone_number,
"password": values.password,
"user_agent":"postman",
"client_host":"local"
}
axios.post(loginUrl, payload = payload)
.then(resp => {
if (typeof resp !== 'undefined') {
if (resp.data.result.is_2fa_active) {
if (resp.data.result.default_2fa === "authenticator_app") {
setAuthenticatorApp(true)
}
if ( resp.data.result.default_2fa === "mobile" || resp.data.result.default_2fa === "email") {
let payloadOtp = {
"type": resp.data.result.default_2fa,
"input": values.phone_number,
"password": values.password,
}
axios.post(otpUrl, payloadOtp).then(response => {
setEmailOrSmsAuth(true)
return response
})
}
}
}
})
}
当我调用这个API时,otp API状态码是200,有效载荷有我想要的所有值,但响应是空的请帮助我,我的代码有什么问题!
我相信你的问题涉及到方方面面。
因为.then
只在POST请求完成时运行,所以响应只能在该回调内部访问。预期的解决方案是将所有的逻辑移到回调中,但是如果有很多后续逻辑,这会变得很混乱。
另一种(通常是首选的)方法是在请求上使用Promise,然后使用await
等待响应。然后,这将把结果返回给具有正确作用域的逻辑的其余部分,从而允许您像使用其他变量一样使用它。我不知道你的POST请求使用的是什么库或方法,但是你想要的库没有预先解决方案,你可以把你的请求包装在一个Promise中并调用它。语法类似于:
const postApiPromise = (loginUrl, payload ) => {
return new Promise((resolve, reject) => {
service.post_api(loginUrl, payload = payload) => {
if (err) return reject(err)
resolve(data)
})
})
}
我意识到这个问题来自服务器。下面是我解决这个问题的方法。
const login = (values) => {
setIsLoading(true);
sessionStorage.setItem('mobile', values.phone_number); //set mobile into local session
sessionStorage.setItem('password', values.password); //set password into local session
const loginUrl = `${BASE_URL(IAM_APP)}/auth/login/`
let payload = {
"input": values.phone_number,
"password": values.password,
"user_agent": "postman",
"client_host": "local"
}
axios.post(loginUrl, payload) //request for login if 2factor authentication is true then send to another component
.then(resp => {
if (resp !== undefined){
if (resp.data?.result?.access_token) {
setToken(resp.data.result)
setTimeout(() => {
window.location.href = DASHBOARD
}, 1000);
} else if (resp?.data?.result.is_2fa_active === true) {
if (resp.data.result.default_2fa === "authenticator_app") {
history.push(LOGIN2FAAUTHENTICATOR);
} else if (resp.data.result.default_2fa === "email") {
history.push(LOGIN2FAEMAIL);
} else if (resp.data.result.default_2fa === "mobile") {
history.push(LOGIN2FASMS);
}
}
}
})
}
then for example in the LOGIN2FASMS route solve issue like this
const otpSent = () => { //send otp to mobile
const otpUrl = `${BASE_URL(IAM_APP)}/auth/2fa/otp/`
let payloadOtp = {
"type": "mobile",
"input": mobile,
"password": password,
}
return axios.post(otpUrl, payloadOtp)
}
useEffect(() => {
otpSent().then(resp => {
if (resp?.data?.result === 'otp sent'){
}
else
otpSent()
}
)
}, [mobile, password]);
yeah, its done ;)