spotify api axios react post request 403 error - reactjs

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/

Related

CSRF Protection with Flask/WTForms and React

Has anyone successfully implemented CSRF protection for a form submitted with React (as a controlled component) to a Flask back-end (ideally with WTForms)? I've seen a lot of partial answers, and one with Django, but couldn't find anything definitive for Flask. My big issue seems to be that I don't know how to send the csrf token to my react front end, store it as a header before submitting my form, then submit my form with the correct token. Any direction would be really helpful.
So, essentially what I did is I set up a route in Flask that can receive both GET and POST requests. React sends a GET request when the component mounts, and Flask responds with the csrf token as a header (done manually). Then React stores this value in state. When the form is submitted, the csrf token from state is sent as a field, similar to the way it is sent in a pure Flask app, where it would be a hidden field. While this technically works, I am curious if this is still vulnerable to CSRF. I think the next best option is to set up CSRF protection on all endpoints, so can try that if this isn't secure.
Flask route:
#app.route('/api/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
print(request.method)
if request.method == 'GET':
return ('', {'csrf_token': form.csrf_token._value()})
elif form.validate_on_submit():
return { 'message': 'Login successful' }, 200
else:
return { 'errors': form.errors }
GET request in componentDidMount:
componentDidMount() {
axios.get('/api/login',{data: null, headers: {'Content-Type': 'application/json'}})
.then(res => {
console.log(res)
this.setState({
csrf: res.headers.csrf_token
});
})
}
POST request when form is submitted:
onSubmitLogin = e => {
e.preventDefault();
const userData = {
username: this.state.username,
password: this.state.password,
csrf_token: this.state.csrf
};
axios({
method: 'post',
url: '/api/login',
data: userData,
headers: {
'content-type': 'application/json'
}
})
.then(res => {
console.log(res);
});
}
Maybe you need flask-security-too lib
https://flask-security-too.readthedocs.io/en/stable/patterns.html#csrf

How can i access the cookie sent as a response from express in react js?

I am using mern stack to make an application. For authentication i am using toke auth with passport authentication and for security reasons i am sending token in cookie. I have a login call which returns a cookie with response. The snippet is below:
res.cookie("cookie_token", token, { maxAge: 84600 });
res.send({
status: "success"
});
I can see the cookie in postman and even in browser in network(xhr request).
I am using axios for making call to the login api in react js.
axios.get(myapiurl, {
headers: {
email: fields.email,
password: fields.password,
"access-control-allow-origin": "*"
}
})
.then(res => {
console.log(res);
}).catch((err) => {
console.log(err);
});
Though i can't find a snippet to access the cookie in react js. How can i parse it? I can't see cookie in response of axios though? How can i access it.
Please try this. Snippet from mdn.
function getCookie(sKey) {
if (!sKey) { return null; }
return document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + sKey.replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1") || null;
}
export function getLoginInfo() {
const cookieToken = getCookie('cookie_token')
console.log(cookieToken)
}

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

How do I fix 'The access token is from wrong audience or resource.' when trying to access Azure's REST api using an MSAL token

I'm creating a node web app that needs to integrate with some azure services using Azure REST API. I'm using the node MSAL library for user login and retrieving an access token for making requests to the Azure REST api. I'm able to login a user successfully and retrieve an access token. However, when I try to make a request to Azure's REST api I am receiving a 401 error that says error="invalid_token", error_description="The access token is from wrong audience or resource."
The web app itself is built with Node LTS and React v16.8.6. It has been deployed in Azure and registered with active directory.
I'm using MSAL v1.0.1 to login a user and retrieve a token when the user lands on the login page.
login.js
import React, { Component } from 'react';
import * as Msal from 'msal';
let msalConfig = {
auth: {
clientId: process.env.REACT_APP_CLIENT_ID,
authority: `https://login.microsoftonline.com/process.env.REACT_APP_TENANT_ID'`,
navigateToLoginRequestUrl: false,
redirect_uri: 'http://localhost:3000/newEntry',
resource: 'https://management.azure.com/'
},
cache: {
cacheLocation: "localStorage",
storeAuthStateInCookie: true
}
};
var msalInstance = new Msal.UserAgentApplication(msalConfig);
var tokenRequest = {
scopes: ['https://management.azure.com/']
}
class Login extends Component {
constructor(props) {
super(props);
this.state = {
response: null,
};
}
componentWillMount() {
// prevent login loop by checking for logged in user and then acquire a token if logged in
if (!msalInstance.getAccount() && !msalInstance.isCallback(window.location.hash)) {
this.login();
} else {
msalInstance.acquireTokenSilent(tokenRequest)
.then(res => localStorage.setItem('access_token', res.accessToken))
.catch(err => console.error(err))
}
}
login = () => {
msalInstance.handleRedirectCallback((error, response) => {
if (error) console.error(error);
console.log(response);
})
msalInstance.loginRedirect(tokenRequest);
}
render() {
return (
<div>
<h2>Login</h2>
</div>
)
}
}
export default Login;
I am successfully returning an access token and putting it in local storage.
On a separate page I am retrieving the MSAL access token from local storage and using it to make a request to retrieve all resources associated with my Azure subscription.
componentWillMount() {
let token = localStorage.getItem('access_token');
let url = 'https://management.azure.com/subscriptions/process.env.REACT_APP_SUBSCRIPTION_ID/resource?api-version=2018-02-14'
fetch(url, {
method: 'GET',
headers: {
'Authorization': `Bearer ${token}`
}
})
.then(response => console.log(response))
.catch(err => console.error(err));
}
I suspect I'm getting the error because there is some discrepancy between the resource value sent with the login request and the scope value sent with the token request.
I've attempted changing the resource value to 'resource': 'https://management.core.windows.net/' per Azure: The access token has been obtained from wrong audience or resource but that didn't change anything.
I've also attempted various scopes including https://management.azure.com/user_impersonation and https://management.azure.com//user_impersonation following this example Access Token do not include access for API with MSAL
The get method is default, and the problem might be in 'Authorization': `Bearer ${token}`.
Sometimes people use different rules, like 'Authorization': token, or 'Token': `Bearer ${token}`.
I see some API using 'S-token': token. try that. I thinkit is because the token did get there.
You are using msal, so resource parameter is not needed in your msalConfig. You can remove it.
Change the scopes to scopes: ['https://management.azure.com/.default'].
So I ended up switching to the ADAL library to see if I would get the same error and I did. I did however realize the resource request URL wasn't correct. The api-version wasn't an accepted version. Once I switched it to 2018-02-01 the request returned 200.

Fetch request to Cloudinary API from with React Component fails

I want to make an HTTP request to the Cloudinary API for pictures in my account. The url necessary looks like this:
https://<<API KEY>>:<<API SECRET>>#api.cloudinary.com/v1_1/<<RESOURCE NAME>>/resources/image
and when I hit this url from the browser, I get what I'm looking for, a beautiful JSON object with all my pictures.
But when I hit the url from within a React component,
componentDidMount() {
this.props.fetchArt();
}
I get the following error:
TypeError: Failed to execute 'fetch' on 'Window': Request
cannot be constructed from a URL that includes credentials:
The action creator looks like
export function fetchArt() {
const url = 'https://'+CLOUDINARY_KEY+':'+CLOUDINARY_SECRET+'#api.cloudinary.com/v1_1/prints20/resources/image';
const request = fetch(url).then(res => res.json())
return {
type: FETCH_ART,
payload: request
}
}
Link to the repo: https://github.com/PantherHawk/prints20-2018
Thanks a million in advance!
If your endpoint requires some sort of authorization you'll need to pass that info inside the headers of your request.
Cloudinary Authentication is done using Basic Authentication over secure HTTP. Your Cloudinary API Key and API Secret are used for the authentication.
fetch('https://api.cloudinary.com/v1_1/CLOUD_NAME/resources/image', {
method: 'get',
headers: {
'Authorization': 'Basic ' + base64.encode(API_KEY + ":" + API_SECRET),
},
}).then(res => res.json())

Resources