在javascript和axios中为来自前端的每个api调用发送firebase身份验证令牌
Posted
技术标签:
【中文标题】在javascript和axios中为来自前端的每个api调用发送firebase身份验证令牌【英文标题】:send firebase authentication token for every api call from frontend in javascript and axios 【发布时间】:2021-06-02 17:48:19 【问题描述】:我正在构建一个使用 firebase 身份验证的网络应用程序。我正在尝试将 firebase 令牌发送到每次调用的后端 API。 我可以检索令牌并将其打印在控制台中,但是每当我尝试将其发送到后端时,令牌似乎都是空的。 我使用的后端是 Python django,
这是我尝试过的,
token.js
function clienttoken()
firebase.auth().onAuthStateChanged(function myuser(user)
if (user)
//window.location.href = 'index.html';
firebase.auth().currentUser.getIdToken(/* forceRefresh */ true).then(function(idToken)
// Send token to your backend via HTTPS
var token = idToken;
window.alert(token);
//return token;
)
);
我能够在控制台中成功打印令牌。
当我尝试在 index.html 中使用它时
<script>
(function ()
var output = document.getElementById('output');
document.getElementById('post').onclick = function mydata ()
var data = document.getElementById('data').value;
var token = clienttoken();
//window.alert(token);
const config =
headers: Authorization: 'Bearer' +token
;
axios.post('http://127.0.0.1:7000/posts/', mydata.data,config)
.then(function (res)
//output.className = 'container-fluid';
resp = JSON.stringify(res.data.body);
resp_new=resp.replace(/\\n/g,'\n')
//output.innerHTML = JSON.stringify(res.data.body);
$("#resp").text(resp_new);
$("#resp").show()
)
.catch(function (err)
output.className = 'container text-danger';
output.innerHTML = err.message;
);
;
)();
</script>
Axios 甚至在获取令牌之前就开始执行,并且每次都会向后端发送一个空令牌。
我尝试使用异步功能 token.js
async function retrievetoken()
firebase.auth().onAuthStateChanged(async function mytoken(user)
if (user)
// User is signed in.
const idtoken = await firebase.auth().currentUser.getIdToken(/* forceRefresh */ true)
//window.alert(token);
return idtoken;
else
// No user is signed in.
window.location.href = 'login.html';
);
index.html
<script>
(function ()
var output = document.getElementById('output');
document.getElementById('post').onclick = function mydata ()
var data = document.getElementById('data').value;
async function retrievetoken()
const token = await clienttoken();
window.alert(token);
;
)();
</script>
我试图打印令牌,但我得到的只是[Object:Promise]
。即使在异步调用之后,也会将空令牌发送到后端。
请帮助我了解如何为每个 API 调用发送 firebase 令牌。
还请找到我的后端编码,
class GetPostList(APIView):
cred = credentials.Certificate(r'pathto/firebase-sdk.json')
firebase_admin.initialize_app(cred)
def post(self,request,format=None):
jwt_token = request.META.get('Authorization')
#jwt_token = request.headers['Authorization']
decoded_token = auth.verify_id_token(jwt_token)
uid = decoded_token['uid']
endpoint = "https://jsonplaceholder.typicode.com/posts/"
header = "Content-type": "application/json;charset=UTF-8"
send_data = request.data
if uid is not None:
response = requests.post(endpoint, json=send_data, headers=header)
return Response(response.json())
else:
return Response('error': 'Token does not exist', status=401)
我认为我确信后端编码看起来不错。但是,我无法从前端为每个 API 调用发送令牌。
【问题讨论】:
为什么要把token
用大括号括起来? (这里: const config = headers: Authorization: 'Bearer' +token ; )
【参考方案1】:
使用回调函数时,return 关键字返回的是回调函数,而不是原始函数。因此,您需要使用 await
关键字来等待 promise 解析,然后返回该值。
为避免这种情况,您应该使用firebase.auth().currentUser
来获取当前用户,而不是为用户登录或注销创建监听器。这还有一个好处,即您的函数不会在用户注销时重新运行等。
async function retrieveToken()
const currentUser = firebase.auth().currentUser;
if (user)
// User is signed in.
const idToken = await firebase.auth().currentUser.getIdToken( /* forceRefresh */ true)
// Because this return statement is no longer in a nested callback function, it now returns properly.
return idtoken;
else
// No user is signed in.
window.location.href = 'login.html';
【讨论】:
以上是关于在javascript和axios中为来自前端的每个api调用发送firebase身份验证令牌的主要内容,如果未能解决你的问题,请参考以下文章
数据未使用 axios 渲染/console.log,使用来自 mongoDB 的数据
React Redux Axios:POST 请求未收到来自 redux 状态的凭据
反应应用程序中来自axios POST的空响应,rails服务器显示201状态
ReactJS/Express Axios POST 返回 404,来自 Postman