React provide default authentication for all request - reactjs

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.

Related

access Nextjs httponly cookie

I'm working on a Nextjs app and I'm using Laravel api for auth and other things.
So I was searching about the best way to store the token that i will get when I sign a user in or sign him up from that Laravel external api and as I found storing it via httponly cookie is the best way and that's what I did using nextjs api routes to store it there.
I create 3 api routes in /api directory for loging the user in and up and out.
but now I'm facing an issue which is how to send this token on each request that i'm sending on client side to that api.
for now I'm using getServerSideProps to get the token and then send it by props to the needed component but this is solution is redundant and not handy at all.
I'm using getServerSideProps just to get it on any page that need to communicate with backend.
so is there any way to forward the token on each request without the need to get the token from server side and send it to client side?
or do u think there is a better way to store the token in somewhere else?
If you have a httpOnly cookie and you don't want to expose it to the client-side, I don't suggest to pass it in getServerSideProps as prop to the component. This will expose your token and will have the risk of scripts accessing the cookie. If the cookie is HttpOnly, it means it cannot be accessed through the client-side script.
Instead, you can create a NextJS api and access your token there. Then call that api in your app.
This is an example of how to access the cookie in nextjs api:
// src > pages > api > endpoint.js
export default async function (req, res) {
// assuming there is a token in your cookie
const token = req.headers.cookie.token;
// Attach the token to the headers of each request
const fetchWithToken = (url, options = {}) => {
options.headers = options.headers || {};
options.headers.Authorization = `Bearer ${token}`;
return fetch(url, options);
};
// Your API logic here
// ...
}
Now in your component in client-side, you can easily the new endpoint in /api/endpoint/ instead of calling the API with the token. In this method, you will never expose the token to the browser:
import { useState, useEffect } from 'react';
const MyComponent = () => {
const [data, setData] = useState(null);
useEffect(() => {
const fetchData = async () => {
const res = await fetch('/api/endpoint');
const data = await res.json();
setData(data);
};
fetchData();
}, []);
// Your component logic here
// ...
};
export default MyComponent;

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.

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

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

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 to implement slack Oauth-2.0 in react js?

I need to implement slack authorization in my project for sending message in channel,Direct message and add reminder .So can anyone suggest me how to implement slack authorization in react project or is there any npm package that i can utilize to implement slack authorization like google authorization.
I had the this problem. Took me ages to solve but anyway here is my solution:
useEffect(() => {
const getdata = async (con) =>{
try{
await axios.get("https://slack.com/api/users.identity",con).then((res) => console.log(res)).catch((err) => console.log(err))
}
catch{
}
}
const gettoken = async () => {
try{
await axios.get("https://slack.com/api/oauth.v2.access",{params: {client_id: sclientId, client_secret: sclientsecret, code: name1[1]}}).then((res) => setData(res.data.authed_user.access_token)).catch((err) => console.log(err));
}catch
{
}
}
gettoken();
const config = {
headers: {
"Access-Control-Allow-Headers": "authorization",
"Access-Control-Allow-Origin": "*",
"Authorization": `Bearer ${ data}`,
"token": data
},
};
getdata(config);
})
so sclientid,sclientsecret, and name1(which stores code) were variables I defined in my code. I had a link(or button) that redirects the user to slack for authorization . code below:
<a href ={`https://slack.com/oauth/v2/authorize?user_scope=identity.basic,identity.email,identity.avatar&client_id=${sclientId}`} ><img src="https://api.slack.com/img/sign_in_with_slack.png" /></a>
after the user has given permission then he is directed back to my site with a code. i used window.location.search to get the code out of the url and store it in name1[1] and then using that my gettoken function sends the client_id,client_secret and code to slack with a get request. this brings back json which includes the token. I then send this token back to slack as a header in a request using my getdata function which returns the user info. To get the client_id ,client_secret and set the redirect url you have to go to apps.slack.com and create an app. Ask me any questions if this is not clear enough

Resources