How to implement slack Oauth-2.0 in react js? - reactjs

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

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.

Combining a ExpressJS Router endpoint with a fetch call to an external enpoint

I am trying to create an Express Router endpoint that will return the CSV file from an external API (Jenkins in this case)
In more detail, what I am trying to achieve is to have a React Frontend call this route on the Express backend and download a CSV file.
BACKEND
The Express route is has this structure:
router.get('/path/latestCsvTestReport', async (req, res) => {
const { channel } = req.params;
return fetch(
`${jenkinsHost}/job/${channel}/${jenkinsPath}/lastSuccessfulBuild/artifact/test_result/report_test.csv`, {
...fetchOptions,
headers: { Authorization: jenkinsAuth},
},
)
.then(r => {
console.log('====== DATA =====', r);
res.setHeader('Content-type', 'text/csv');
res.setHeader('Cache-Control', 'no-cache');
res.send(r)
})
.catch((err) => {
// console.log(err);
res.status(404);
res.send('report not found');
});
});
and the URL called in the fetch returns a CSV file.
FRONTEND
I am calling the Express endpoint from a method on the React frontend using the following function, which utilised the file-saver library:
async function triggerReportDownload(chlId) {
console.log('===== CSV Request ====')
const resource = `/api/jenkins/${chlId}/latestCsvTestReport`;
saveAs(resource, "report.csv")
}
which is triggered by the click of a button on the FrontEnd.
At the moment, the button, triggers a download but the csv downloaded only contains:
{"size":0 timeout:0}
I am certain I am doing something completely wrong on the way the backend returns the CSV from the fetch call, but for the life of me I do not seem to be able to find the way to formulate the response. Any help/direction towards fixing this would be greatly appreciated.
The solution to this is to simply things as possible (being a newbie I had overcomplicated things). So here we are:
Backend
Import the utils library and then create a stream:
import util from 'util';
const streamPipeline = util.promisify(require('stream').pipeline);
This is then called from the Express router:
router.get('/jenkins/:channel/latestCsvTestReport.csv', async (req, res) => {
const { channel } = req.params;
const response = await fetch(
`${jenkinsHost}/job/${channel}/${jenkinsPath}/lastSuccessfulBuild/artifact/test_result/report_test.csv`, {
...fetchOptions,
headers: { Authorization: jenkinsAuth },
},
);
res.setHeader('Content-disposition', `attachment; filename=report_test_${Date.now()}.csv`);
res.set('Content-Type', 'text/csv');
return streamPipeline(response.body, res);
});
Frontend
Use windows.open to get the download file
async function triggerReportDownload(chlId) {
window.open(`/api/jenkins/${chlId}/latestCsvTestReport.csv`);
}

spotify api axios react post request 403 error

makePlaylist = event => {
event.preventDefault()
let token = localStorage.getItem('token')
let playlist = {name: this.state.text, public:false}
axios.post(
`https://api.spotify.com/v1/users/${this.state.user_id}/playlists`, playlist,
{headers: {
"Authorization": 'Bearer ' + token
}
}
)
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error)
})
}
and I get the following error
https://api.spotify.com/v1/users/my_user_id_here/playlists 403 error
I looked up the documentation online at
https://developer.spotify.com/documentation/web-api/reference/playlists/create-playlist/
and it looks like I'm setting things up as far as I can tell. Anyone know what I'm doing wrong with the request? I know the access token is valid.
"Trying to create a playlist when you do not have the user’s authorization returns error 403 Forbidden." Make sure that the Spotify app that you made in Dashboard has the proper scope permissions on the user you are trying to create the playlist for. Here is the scope for creating a private playlist: https://developer.spotify.com/documentation/general/guides/scopes/#playlist-modify-private
Here is the tutorial for setting up authorization with passing in a scope:
https://developer.spotify.com/documentation/general/guides/authorization-guide/

Resources