DEV Community

Sai Avinash Duddupudi
Sai Avinash Duddupudi

Posted on

Fetch in react js returns 401 (unauthorized) while passing access token

Hello everyone,

I am trying to pass access token to an API that returns data through fetch from DATA_API but I am getting 401 unauthorized error.

When I opened Network Tab, I observed that the auth headers did not injected and hence the 401 error is coming. The token is also getting fetched from ACCESS_TOKEN_API and its getting logged in the console.

Here is my code. Please suggest a workaround.

import React, { useState, useEffect } from "react";
import {Col } from 'antd';
import { Link } from "react-router-dom";
import AntDTable from '../shared/AntDTable';
import iInnerLoader from '../shared/iInnerLoader';
const columns = [
  {
    title: 'Account Name',
    dataIndex: 'name',
    render: (text, record) => (
      <Link to={`/all-customers/tenants/?tenant_id=${record.id}&customer=${record.name}`}>{record.name.toUpperCase()}</Link>
    ),
  },
  {
    title: 'Total Tenants',
    dataIndex: 'tenantCount',
  }
];
const useFetch = (url, headers) => {
  const [data, setData] = useState([]);
  const [loading, setLoading] = useState(true);
    useEffect(async () => {
      const response = await fetch(url,headers)
      const data = await response.json()
      // console.log(data)
      setData(data)
      setLoading(false)
    },[]);
    return {data, loading};
}
​
export default function CreateTestcaseStep2() {
  const [token, setToken] = useState([]);
    useEffect(async () => {
      const response = await fetch('ACCESS_TOKEN_API',{
        method : 'POST',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/x-www-form-urlencoded'
        },
        body : 'body_part'
      })
      const data = await response.json()
      // console.log(data)
      setToken(data)
    },[]);

console.log("token is ", token.access_token) // TOKEN IS GETTING PRINTED HERE
var api_headers={ method: 'GET',
  headers: {'Authorization': `Bearer ${token.access_token}`,
  "Access-Control-Allow-Origin" : "*", 
  "Access-Control-Allow-Credentials" : true },
}
console.log("headers ", api_headers)
  const {data, loading} = useFetch('DATA_API', api_headers)
  return (
    <>
      <Col md={24} sm={24} className="p-0">
        <div className="customer-list">
            <div className="customer-list-header">
              Customer Accounts
            </div>
            <br/>
            <div className="customer-list-content">
            {loading? <iInnerLoader isDisplayLabel={true} label={"Loading Customers"} /> :
             <AntDTable columns={columns} data={data.data} pagination={true} height={390}/>}
            </div>
        </div>
    </Col>
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

Top comments (4)

Collapse
 
tqbit profile image
tq-bit • • Edited

In your fetch request in useFetch, you are directly assigning headers as a second function parameter to the fetch method.

Try and rewrite your useFetch - function to assign the headers to the options object and pass this into the fetch() - function.

If that won't work, please state what backend you're using. For reference, you can also check MDN

const useFetch = (url, headers) => {
  const [data, setData] = useState([]);
  const [loading, setLoading] = useState(true);
  // Assign headers to options object
  const options = { headers: headers }
    useEffect(async () => {
      // Pass options as second argument instead of headers
      const response = await fetch(url,options)
      const data = await response.json()
      // console.log(data)
      setData(data)
      setLoading(false)
    },[]);
    return {data, loading};
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
saiavinashiitr profile image
Sai Avinash Duddupudi • • Edited

Hey. I am not directly assigning headers as second param in useFetch. If you observe api_headers it contains headers, method, etc.... have you misunderstood this? My bad, I shouldn't have named the second param as headers

Below is api_headers which I am passing which again consists of headers, method etc...

var api_headers={ method: 'GET',
  headers: {'Authorization': `Bearer ${token.access_token}`,
  "Access-Control-Allow-Origin" : "*", 
  "Access-Control-Allow-Credentials" : true },
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
tqbit profile image
tq-bit •

Ye, that slipped my attention, my apologies.
The rest of your code doesn't look suspicious. Since you're storing the token in your state, you could try and instead save it as a clientside cookie, explicitly sending it to your backend. Else, I'd see for the backend documentation or verify error logs, if available.

Collapse
 
saiavinashiitr profile image
Sai Avinash Duddupudi • • Edited

Tried it. Facing the same issue again. Please refer below screenshot

i.imgur.com/07swAGc.png

Also, I do not have control over the backend API's