【问题标题】:Sending the bearer token with axios使用 axios 发送不记名令牌
【发布时间】:2017-04-20 16:07:02
【问题描述】:

在我的 react 应用程序中,我使用 axios 来执行 REST api 请求。

但它无法随请求发送 Authorization 标头。

这是我的代码:

tokenPayload() {
  let config = {
    headers: {
      'Authorization': 'Bearer ' + validToken()
    }
  }
  Axios.post( 
      'http://localhost:8000/api/v1/get_token_payloads',
      config
    )
    .then( ( response ) => {
      console.log( response )
    } )
    .catch()
}

这里的validToken() 方法会简单地从浏览器存储中返回令牌。

所有请求都有一个 500 错误响应,说明

无法从请求中解析令牌

从后端。

如何在每个请求中发送授权标头?你会推荐任何其他带有反应的模块吗?

【问题讨论】:

  • 我认为这根本不是axios 问题。检查你的 validToken() 函数,它返回的东西是你的服务器不理解的。
  • 我仔细检查了函数,这里也用token字符串代替了函数,还是一样

标签: reactjs rest token axios access-token


【解决方案1】:
const config = {
    headers: { Authorization: `Bearer ${token}` }
};

const bodyParameters = {
   key: "value"
};

Axios.post( 
  'http://localhost:8000/api/v1/get_token_payloads',
  bodyParameters,
  config
).then(console.log).catch(console.log);

第一个参数是 URL。
第二个是将随您的请求发送的 JSON 正文。
第三个参数是标题(除其他外)。这也是 JSON。

【讨论】:

  • 您错过了承载和令牌之间的空格 - 然后它会起作用。
  • Doctor's post: "key: "value" 有一个应该被删除的引号......但修复这个问题确实让身份验证适用于我的 react-native 应用程序。
  • @mediaguru 谢谢评论。我修好了(我想)!引用必须是由编辑答案的人介绍的......
  • Bearer 应该与大写 B 一起使用,不是吗?
  • @Alizadeh118 是的,根据 HTTP 规范。但是很多 api 并不坚持正确的大小写。
【解决方案2】:

这是在 axios 中设置授权令牌的一种独特方式。为每个 axios 调用设置配置不是一个好主意,您可以通过以下方式更改默认授权令牌:

import axios from 'axios';
axios.defaults.baseURL = 'http://localhost:1010/'
axios.defaults.headers.common = {'Authorization': `bearer ${token}`}
export default axios;

编辑,感谢 Jason Norwood-Young。

有些API要求bearer写成Bearer,所以你可以这样做:

axios.defaults.headers.common = {'Authorization': `Bearer ${token}`}

现在您无需为每个 API 调用设置配置。现在授权令牌设置为每个 axios 调用。

【讨论】:

  • Bearer 对于某些 API 需要大写(我发现很难)。
  • 这应该是被接受的答案。这是更好的方法。
  • @FaizanMubasher 如果您使用不同的服务器则不会
  • @Musculaa 问题不在于不同的服务器?。
  • 为了从函数或本地存储中加载令牌,我们需要拦截器
【解决方案3】:

您可以创建一次配置并在任何地方使用它。

const instance = axios.create({
  baseURL: 'https://some-domain.com/api/',
  timeout: 1000,
  headers: {'Authorization': 'Bearer '+token}
});

instance.get('/path')
.then(response => {
    return response.data;
})

【讨论】:

  • 这个例子中传过来的token值在哪里?对于我的应用程序,成功登录后,令牌将在标头或正文中传递回 api。
  • 这里是headers: {'Authorization': 'Bearer '+token}
  • 如果是POST请求如何传递数据
  • 对于那些想知道可以从哪里传递令牌值的人,这里是 es6 语法 - const instance = (token) => axios.create({ baseURL: `${config.API_URL}`, timeout: 1000, headers :{ 'authorization': 'Bearer ' + token } })
【解决方案4】:

axios.post 的第二个参数是data(不是config)。 config 是第三个参数。详情请看:https://github.com/mzabriskie/axios#axiosposturl-data-config

【讨论】:

    【解决方案5】:

    通过使用 Axios 拦截器:

    const service = axios.create({
      timeout: 20000 // request timeout
    });
    
    // request interceptor
    
    service.interceptors.request.use(
      config => {
        // Do something before request is sent
    
        config.headers["Authorization"] = "bearer " + getToken();
        return config;
      },
      error => {
        Promise.reject(error);
      }
    );
    

    【讨论】:

    • 这是用 axios 配置标头的社区标准吗?
    • @5ervant 我在使用这种方法时度过了一段非常糟糕的时光。这很痛苦,所以我不推荐它。
    • @ankush981 这种方法有什么不好,你推荐哪一种?
    • @NenadKaevik 我试图覆盖一个特定的用例(响应拦截):让用户知道服务器何时响应 403。人们通常将令牌验证步骤放在组件加载期间,但假设您的令牌在验证后几秒钟就失效了(无论出于何种原因)。现在,当此人单击按钮时,我希望他们知道他们已退出。使用拦截器很难做到这一点,因为它们会添加全局行为。我进入了重新加载循环,因为请求拦截器总是会添加令牌,而响应拦截器会重定向
    • @NenadKaevik 所以,也许流程很难实现,或者我使用了错误的方法,但从那时起我开始讨厌拦截器。
    【解决方案6】:

    如果您想在标头中传递令牌后获取一些数据,以便尝试此代码

    const api = 'your api'; 
    const token = JSON.parse(sessionStorage.getItem('data'));
    const token = user.data.id; /*take only token and save in token variable*/
    axios.get(api , { headers: {"Authorization" : `Bearer ${token}`} })
    .then(res => {
    console.log(res.data);
    .catch((error) => {
      console.log(error)
    });
    

    【讨论】:

      【解决方案7】:

      这行得通,我只需要在我的app.js 中设置一次令牌:

      axios.defaults.headers.common = {
          'Authorization': 'Bearer ' + token
      };
      

      然后我可以在我的组件中发出请求而无需再次设置标头。

      "axios": "^0.19.0",

      【讨论】:

      • 我不知道为什么,但是通过这种方式,它在 iOS 设备上的 Safari 上不起作用:(
      • 对我来说很简单的方法
      【解决方案8】:

      以防万一有人遇到同样的问题。

      这里的问题是当传递没有数据的标头时,标头的配置将在有效负载数据中,所以我需要传递 null 而不是数据,然后设置标头的配置。

      const config = {
               headers: {
                   "Content-type": "application/json",
                    "Authorization": `Bearer ${Cookies.get("jwt")}`,
               },
          };    
      axios.get(`${BASE_URL}`, null, config)
      

      【讨论】:

        【解决方案9】:

        我使用一个单独的文件来初始化 axios 实例,同时我添加了拦截器。然后在每次调用中,拦截器都会为我将token添加到请求头中。

        import axios from 'axios';
        import { getToken } from '../hooks/useToken';
        
        const axiosInstance = axios.create({
          baseURL: process.env.REACT_APP_BASE_URL,
        });
        
        axiosInstance.interceptors.request.use(
          (config) => {
            const token = getToken();
            const auth = token ? `Bearer ${token}` : '';
            config.headers.common['Authorization'] = auth;
            return config;
          },
          (error) => Promise.reject(error),
        );
        
        export default axiosInstance;
        
        

        这是我在服务文件中使用它的方式。

        import { CancelToken } from 'axios';
        import { ToolResponse } from '../types/Tool';
        import axiosInstance from './axios';
        
        export const getTools = (cancelToken: CancelToken): Promise<ToolResponse> => {
          return axiosInstance.get('tool', { cancelToken });
        };
        
        

        【讨论】:

        • 清除解决方案。你能给出 ToolResponse 文件的例子吗?谢谢。
        【解决方案10】:

        有很多好的解决方案,但我用这个

        let token=localStorage.getItem("token");
        
        var myAxios=axios.create({
          baseURL: 'https://localhost:5001',
          timeout: 700,
          headers: {'Authorization': `bearer ${token}`}
        });
        
        export default myAxios;
        
        

        然后我将 myaxios 导入我的文件并

        myAxios.get("sth")
        

        【讨论】:

          【解决方案11】:

          // usetoken 是我抓狂的钩子

          export const useToken = () => {
               return JSON.parse(localStorage.getItem('user')).token || ''
          }
          const token = useToken();
          
          
          
          const axiosIntance = axios.create({
              baseURL: api,
              headers: {
                  'Authorization':`Bearer ${token}`
              }
          });
          
          axiosIntance.interceptors.request.use((req) => {
              if(token){
                  req.headers.Authorization = `Bearer ${token}`;
              }
              return req;
          })
          

          【讨论】:

            【解决方案12】:

            axios 本身带有两个有用的“方法”interceptors,它们只是请求和响应之间的中间件。所以如果你想在每个请求中发送令牌。使用interceptor.request

            我做了一个可以帮助你的包:

            $ npm i axios-es6-class
            

            现在你可以使用 axios 作为类了

            export class UserApi extends Api {
                constructor (config) {
                    super(config);
            
                    // this middleware is been called right before the http request is made.
                    this.interceptors.request.use(param => {
                        return {
                            ...param,
                            defaults: {
                                headers: {
                                    ...param.headers,
                                    "Authorization": `Bearer ${this.getToken()}`
                                },
                            }
                        }
                    });
            
                  this.login = this.login.bind(this);
                  this.getSome = this.getSome.bind(this);
               }
            
               login (credentials) {
                  return this.post("/end-point", {...credentials})
                  .then(response => this.setToken(response.data))
                  .catch(this.error);
               }
            
            
               getSome () {
                  return this.get("/end-point")
                  .then(this.success)
                  .catch(this.error);
               }
            }
            

            我的意思是 middleware 的实现取决于您,或者您是否更愿意创建自己的 axios-es6-class https://medium.com/@enetoOlveda/how-to-use-axios-typescript-like-a-pro-7c882f71e34a 这是它来自的中型帖子

            【讨论】:

              猜你喜欢
              • 2021-12-09
              • 1970-01-01
              • 2023-03-28
              • 2019-04-07
              • 2020-03-19
              • 2018-07-19
              • 1970-01-01
              • 2021-12-26
              • 2019-02-24
              相关资源
              最近更新 更多