首页 > 解决方案 > 如何正确读取 NextJS 中的 Axios 授权令牌以获取需要身份验证的请求?

问题描述

好吧,我有一个组件需要令牌才能从数据库中获取数据。用户通常在成功登录后获得令牌:

  const loginAuth = (loginData, history) => async () => {
    const res = await api.post(`/auth/login`, loginData);

    if (res.statusText === `OK`) {
      if (res.data.data) {
        history.push(`/auth/validatetwofactorauth/${res.data.data._id}`);
        return res.data;
      }

      setAuthToken(res.data.token);
      history.push('/posts');
    } else {
      console.log('error');
      // setError(res.data.error);
    }
  };

正如你们所看到的,我正在调用一个名为 的方法sethAuthToken,所述函数如下所示:

export const setAuthToken = (token) => {
  if (token) {
    if (typeof window !== 'undefined') {
      api.defaults.headers.common['Authorization'] = `Bearer ${token}`;
      api.defaults.headers['Authorization'] = `Bearer ${token}`;
      localStorage.setItem('xAuthToken', token);
    }
  } else {
    delete api.defaults.headers.common['Authorization'];
    delete api.defaults.headers['Authorization'];
    localStorage.removeItem('xAuthToken');
    deleteCookie('xAuthToken', '/');
  }
};

收到令牌后,上面的函数将其传递给api.default.headers.common; 这是我的api

import axios from 'axios';
import { API_URL } from '../config';

const api = axios.create({
  baseURL: `${API_URL}/api/v1`,
  headers: {
    'Content-Type': `application/json`
  }
});

console.log('API', api.defaults);
// So far everything works great since I can actually see the token being
// retrieved in the previous console log()

api.interceptors.response.use(
  (res) => res,
  (err) => {
    return Promise.reject(err);
  }
);

export default api;

到目前为止,一切都很好!

现在,问题出现在以下请求和组件上。该组件从需要不记名令牌的请求中获取数据(现在应该可用)

import { useEffect, useState, useContext } from 'react';
import { withRouter } from 'next/router';
// ACTIONS
import { getTimelineFromServer } from '@/actions/post';
// HELPERS
import NothingFoundAlert from '@/layout/NothingFoundAlert';
import privateRoutes from '@/routing/privateRoutes';
import AuthContext from '@/routing/authContext';
// REACSTRAP
import CardColumns from 'react-bootstrap/CardColumns';
// NESTED COMPONENTS
import Single from './single';

export const getServerSideProps = async (context) => {
  const params = `?page=${context.query.page}&limit=${context.query.limit}&sort=${context.query.sort}&status=published`;
  const data = (await getTimelineFromServer(params)()) || []; // Get videos

  if (!data) {
    return { notFound: true };
  }

  return {
    props: {
      params: params,
      serverPosts: data.data,
    }
  };
};

const Timeline = ({
  params,
  serverPosts,
  router
}) => {

  const [posts, setPosts] = useState([]);
  useEffect(() => {
    setPosts(serverPosts);
  }, [params]);

  const { auth } = useContext(AuthContext);
  
    return posts?.length > 0 ? (
        <CardColumns>
            {posts.map((post, index) => (
                <Single
                    key={post._id}
                    post={post}
                    objects={posts}
                    auth={auth}
                />
            ))}
        </CardColumns>
    ) : (
        <NothingFoundAlert />
    )
};

export default withRouter(privateRoutes(Timeline));

需要它的功能是getTimelineFromserver(params)() || []; 这是它的样子:

export const getTimelineFromServer = (params) => async (dispatch) => {
  console.log(api.defaults.headers.common);
  try {
    const res = await api.get(`/posts/timeline${params}`);
    console.log('Get timeline', api.defaults.headers.common);

    return res.data;
  } catch (err) {
    return { msg: err?.response?.statusText, status: err?.response?.status };
  }
};

现在,我假设错误在api.defaults.headers.common因为当我 console.log-it 时,它只返回{ Accept: 'application/json, text/plain, */*' }.

总而言之:令牌因某种原因被删除?

谢谢,我知道这篇文章很长,但我不会问我以前是否没有尝试过;现在,我没有主意了。

注意:我有一个与上述组件一起使用的 privateRoutes HOC,但我认为这与获取无关,因为它唯一要做的就是验证是否找到 X 令牌,否则,将用户重定向到/aut/login

标签: javascriptreactjsaxiosnext.js

解决方案


推荐阅读