使用axios发送承载令牌


117

在我的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,表示

无法从请求中解析令牌

从后端开始。

如何随每个请求发送授权标头?您会推荐其他任何带有react的模块吗?


我认为这根本不是axios问题。检查您的validToken()功能,它返回您的服务器不了解的内容。
xiaofan2406 '16

我仔细检查了该函数,并在此处使用了令牌字符串而不是该函数,仍然是相同的
rakibtg,2016年

Answers:


140
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也是如此。


4
您错过了载体和令牌之间的空格-这样就可以了。
十二月

医生的帖子:“键:“值””中的引号应删除...但是修复后的确使auth可以为我的react-native应用程序使用
。– mediaguru

1
@mediaguru Thx发表评论。我修好了(我想)!引用必须是由编辑答案的人介绍的...
医生

2
Bearer应该与大写B一起使用,不是吗?
Alizadeh118

1
@ Alizadeh118是的,根据HTTP规范。但是许多API并不坚持正确的大小写。
OneHoopyFrood

60

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

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调用。


18
Bearer需要大写一些API(我发现很难)。
詹森·诺伍德·杨


22

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

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

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

在此示例中,令牌的值从哪里传递?对于我的应用程序,成功登录后,令牌将在标头或正文中传递回api。

它在这里headers: {'Authorization': 'Bearer '+token}
M.suleman Khan

如果是POST请求,如何传递数据
M.suleman Khan

对于那些想知道从哪里可以传递令牌的值的人,这里是es6语法const instance = (token) => axios.create({ baseURL: `${config.API_URL}`, timeout: 1000, headers :{ 'authorization': 'Bearer ' + token } })
Jeet

18

通过使用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);
  }
);

1
这是使用axios配置标头的社区标准吗?
5ervant

@ 5ervant使用这种方法时,我的时间非常丑陋。这很痛苦,我不建议这样做。
ankush981

@ ankush981这种方法有什么不好的地方,您推荐哪种方法?
Nenad Kaevik

1
@NenadKaevik有一个我要介绍的特殊用例(响应拦截):让用户知道服务器何时说403作为响应。人们通常将令牌验证步骤放在组件加载期间,但是假设您的令牌在验证后几秒钟就失效了(无论出于何种原因)。现在,当此人单击一个按钮时,我希望他们知道他们已经注销。使用拦截器添加全局行为很难做到这一点。我进入了一个重载循环,因为请求拦截器将始终添加令牌,而响应拦截器将重定向
ankush981

@NenadKaevik所以,也许流程很难实现,或者我使用了错误的方法,但是从那时起,我开始讨厌拦截器。
ankush981

9

如果要在标题中传递令牌后想要一些数据,请尝试以下代码

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)
});

2

这有效,我只需要在我的令牌中设置一次app.js

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

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

"axios": "^0.19.0",


我不知道为什么,但是用这种方式在iOS设备上的Safari上不起作用:(
ZecKa

0

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 它是中发布它来自哪里


-4

这也是我也面临的问题。您传递的令牌不正确。

只需对令牌进行硬编码并通过,您将获得正确的响应。但是,如果令牌没有在单引号''中传递,那么它肯定会失败。它必须采用“授权”格式:“ Bearer YzE5ZTdiMjVlYzM5NjA2MGJkZTM5NjVlOTQ5YMmQ5ZjMwYjA0YmEzZmZjN2I1MmI4MDJkNQ”,在此位置必须非常重要,并且在单引号内也必须很重要。

var token = "YzE5ZTdiMjVlYzM5NjA2MGJkZTM5NjVlOTQ5YMmQ5ZjMwYjA0YmEzZmZjN2I1MmI4MDJkNQ";

var headers = {
  Authorization: "Bearer " + token,
  Accept: "application/json, text/plain, */*",
  "Content-Type": "application/json"
};

IMP:上面的代码可以工作,但是如果您发布类似的内容:

'授权':'承载者'+ YzE5ZTdiMjVlYzM5NjA2MGJkZTM5NjVlOTQ5YMmQ5ZjMwYjA0YmEzZmZjN2I1MmI4MDJkNQ

或----下面的代码也会失败,我希望你能理解基本的区别

var token = YzE5ZTdiMjVlYzM5NjA2MGJkZTM5NjA0YmEzZmZjN2I1MmI4MDJkNQ;

var headers = {
  Authorization: "Bearer " + token,
  Accept: "application/json, text/plain, */*",
  "Content-Type": "application/json"
};
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.