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