I want a simple authentication with bearer token and rest api which should be stored in local storage and be refresh in given time in REACT - reactjs

I want a simple authentication with bearer token and rest API which should be stored in local storage and be refreshed in the given time in REACt.
as I know react is a library and tends to do simple work that concerns on Effective UI and Ux. What about HTTPS request stuff and also authentication . I guess Axios should be the fine approach for HTTP request but using third-party library is sick n RWACt especially if you are a beginner who doesn't have a much understanding of promises than react makes you have a nightmare. Any Solution will be great.

Use axios for this purpose. you can use it like this :
axios.post('/login', data)
.then(response => {
localStorage.setItem('token', response.data.token);
});
Also you can use axios interceptors for this purpose. It will run for every request call. for validating and setting headers to requests like this:
const config = {url:'https://...',timeout:10000}
const instance = axios.create({
baseURL: config.url,
timeout: config.timeout
});
instance.interceptors.request.use(
config => {
const token = localStorage.getItem('token')
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
error => Promise.reject(error)
);

Related

How to hide authorization bearer token from header?

I want to hide some information such as bearer token and API key in header. I have been heard about ssr and using proxy to hide that information, but how? Can someone tell me how to do that? Or is that possible to do in client side?
I tried with some ssr that fetch in react, but it doesn't work for me. I also tried with proxy, but that works for API key that didn't need a dynamically params like user token.
To use server-side rendering (SSR), you will need to install and import the following packages: express, cors, and Axios. The cors middleware allows for Cross-Origin Resource Sharing, while Axios is used to make HTTP requests to external APIs or databases, and handle the response data asynchronously. By setting the headers with Axios, you can pass along sensitive information such as API keys and bearer tokens. After receiving the data back, you can destructure it from the Axios response and then send it back to your users by using the res.json() method.
const cors = require('cors');
const axios = require('axios');
const app = express();
app.use(cors());
app.get('/api/data', async (req, res) => {
try {
const { data } = await axios.get('https://api.example.com/data', {
headers: {
Authorization: `Bearer ${process.env.BEARER_TOKEN}`,
'API-Key': process.env.API_KEY,
},
});
res.json(data);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.listen(3000, () => {
console.log('Server started on port 3000');
});

Making authFetch from react-token-auth doesn't use access token

I'm building a webapp using react and flask. I'm currently implementing user login features using react-token-auth and flask_praetorian. I've already created my back-end functions that handle logging in and can successfully return a token. However, I am now having issues with making an authenticated request.
My flask function
#app_login.route('/get_username')
#flask_praetorian.auth_required
def protected():
response = jsonify({'username': flask_praetorian.current_user().username})
return response
and on react
const fetchUsername = () => { authFetch(`http://${configData.LOCAL_SERVER}:${configData.WEBAPP_PORT}/get_username`).then(response => {
return response.json()
}).then(response => {
console.log(response)
})
}
I'm using the default createAuthProvider as shown on the react-token-auth project page
export const { useAuth, authFetch, login, logout } = createAuthProvider({
getAccessToken: session => session.accessToken,
storage: localStorage,
onUpdateToken: token =>
fetch(`http://${configData.LOCAL_SERVER}:${configData.WEBAPP_PORT}/app_login/refresh`, {
method: 'POST',
body: token.refreshToken,
}).then(r => r.json()),
});
Whenever I make a request, I get a 401 (UNAUTHORIZED) and react returns the error 'authFetch' was called without access token. Probably storage has no session or session were expired
I've checked my local storage and I can see that the key is there:
Storage {persist:root: '{"player":"{\\"value\\":{\\"name\\":\\"\\",\\"access_toke…_persist":"{\\"version\\":-1,\\"rehydrated\\":true}"}', REACT_TOKEN_AUTH_KEY: '"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE2…5OX0.rTBCD7YPD8wrB95v1j9oazNLusKOPErI5jed_XWXDhU"', length: 2}
I'm really trying to avoid using technologies like Redux so any assistance regarding this specific setup would be great.

React provide default authentication for all request

I'm using React with axios mainly. There I have an interceptor for API calls to refresh my JWT token when it expires.
<img src="/media/cache/img.jpg" alt={row.id} width={45} height={45}>
These are also loaded from the server and authentication is needed. But when the token expires and no API query is needed, these images won't load because the token is invalid and authentication is required for these images.
Can I somehow achieve that even in these scenarios the tokens are refreshed correctly before loading the image?
You can use axios to fetch images as well. It looks something like this:
const url = "/media/cache/img.jpg";
const [objectURL, setObjectURL] = useState("");
useEffect(() => {
axios
.get(url, {
responseType: "blob",
})
.then((res) => {
const new_blob = new Blob([res.data], { type: "image/jpg" });
setObjectURL(URL.createObjectURL(new_blob));
});
}, []);
<img src={objectURL} alt={row.id} width={45} height={45}>
Now you can modify this to use your "interceptor for API calls" to refresh your token.

NextAuth: How can I attach my JWT token to every axios call?

I am building a Next.js application.
For authentication, I am using NextAuth.
For making HTTP calls, I am using Axios.
The problem I am facing is that I want to attach the JWT with every axios call I make.
I have an axios instance created as:
axios-client.js
const ApiClient = () => {
const defaultOptions = {
baseURL,
};
const instance = axios.create(defaultOptions);
instance.interceptors.response.use(
(response) => {
return response;
},
(error) => {
console.log(`error`, error);
throw new Error(error.response.data.message);
},
);
return instance;
};
export default ApiClient();
I can get the jwt from getSession() function provided by next-auth.
But the problem is that function is asynchronous. If I try to get jwt from this from the getSession() function, I always get a "Promise" instead of value.
PS: I am using Strapi which sends the JWT after successful login.
Why can't you await the response from getSession() and add it as a header to your request. Note that you don't have to reinitialize axios client each time, you can reuse it.

How could I pass token from cookies to each request using mobx?

I'm writing a web application with Next.js and mobx.
How can I pass token (from cookies) for each request to API? Sometimes I should take it from the browser and sometimes from server side (context object).
Notice, that I make requests in mobx actions (#action).
Thanks in advance!
It depends on the way you are calling the API.
You can achieve that with Axios for example:
const token = localStorage.get('access_token');
const { data } = awit axios('/api/users', { headers: { Authorization: `bearer ${token}` } });

Resources