I'm scratching my head at this problem, I'm implementing Instagrams basic display API using Wix's new editor-x. My code works if I run it on the client side, I get an access token, however it doesn't when I import the getAccessToken function from the server side, the function runs but I get an invalid auth code.
I think there maybe an issue passing the code variable?
frontend code:
import wixLocation from 'wix-location'
import {getAccessToken} from 'backend/instagram'
let query = wixLocation.query; //get auth code from URL param
let code = query.code
console.log(code) //check code is correct
if(code){
const token = await getAccessToken(code) //request accesstoken
console.log(token) //log token
}
backend code:
import {fetch} from 'wix-fetch'
export async function getAccessToken(code) {
const url = "https://api.instagram.com/oauth/access_token"
const options = {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: `client_id=id&client_secret=secret&grant_type=authorization_code&redirect_uri=uri&code=${code}`
}
try {
const data = await fetch(url,options)
const token = await data.json()
return token
} catch(error) {
return error
}
}
Related
I have been trying to retreive the access token for the paylocity API. I am able to get it through postman with the client id and client secret however when I try and retrieve it with Node.js I get the message {"error":"invalid_client"}.
Here is my code
const apikey = {user name};
const secret = {password};
const url = "https://api.paylocity.com/IdentityServer/connect/token";
const authorizationTokenInBase64 = Buffer.from(
`${apiKey}:${secret}`
).toString("base64");
const body = "grant_type=client_credentials&scope=WebLinkAPI";
let config = {
headers: {
Authorization: `Basic ${authorizationTokenInBase64}`,
"Content-Type": `application/x-www-form-urlencoded`,
},
};
try {
const response = await axios.post(url, body, config);
} catch (error) {
console.log("error", error.response.data);
}
So i been trying to get access to the reddit api.
I registered to reddit. verified my mail. opened an app and got my credentials.
Followed this official documentation and also came across to this tutorial
All my efforts have failed and don't get any respond.
I am using nodejs. but also tried in postman and failed.
Tried 2 options using fetch and using axios:
const axios = require('axios');
const fetch = require('node-fetch')
const { URLSearchParams } = require('url')
class RedditApi {
clientId2 = "get ur own credentials by opening an app here https://www.reddit.com/prefs/apps";
clientSecret2 = "get ur own credentials by opening an app here https://www.reddit.com/prefs/apps";
authenticationUrl = `https://www.reddit.com/api/v1/access_token`;
BASE_URL = 'https://www.reddit.com/';
tokenAuth = null;
tokenExpirationTime = null;
currencyObj = null;
constructor(currencyObj) {
this.currencyObj = currencyObj;
console.log("constructor service")
}
async getAuthToken() {
const bodyParams = new URLSearchParams({
grant_type: "https://oauth.reddit.com/grants/installed_client",
device_id: "DO_NOT_TRACK_THIS_DEVICE"
});
console.log(this.clientId2, 'this.clientId');
debugger;
const headersObj = {
'Authorization': `Basic ${Buffer.from(`${this.clientId2}:`).toString('base64')}`,
'Content-Type': 'application/x-www-form-urlencoded',
};
let response = null;
try {
response = await axios.post(this.authenticationUrl,
bodyParams,
{
headers: headersObj
});
debugger;
} catch (error) {
debugger;
console.error(error);
console.log(error.stack);
return null;
}
}
async getAuthToken2() {
try {
// Creating Body for the POST request which are URL encoded
const params = new URLSearchParams()
params.append('grant_type', 'https://www.reddit.com/api/v1/access_token')
params.append('device_id', 'DO_NOT_TRACK_THIS_DEVICE')
// Trigger POST to get the access token
const tokenData = await fetch('https://oauth.reddit.com/grants/installed_client', {
method: 'POST',
body: params,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': `Basic ${Buffer.from(`${this.clientId2}:`).toString('base64')}` // Put password as empty
}
}).then(res => {
debugger;
return res.text()
})
debugger;
if (!tokenData.error) {
debugger;
res.send(trendingResult)
}
res.status(tokenData.error).send(tokenData.message)
} catch (error) {
debugger;
console.log(error)
}
}
}
module.exports = RedditApi;
when using axios i get this respond: "Request failed with status code 401"
When using fetch i get this respond: "'403 Forbidden\nRequest forbidden by administrative rules.\n\n'"
Anybody knows what is the problem and how can i fix it?
Many thanks!
*My goal here is to get the location of bikes from a bike-sharing company's API.
I did Steps 1 and 2 using Postman. but ill try to integrate it into my code once I get the hang of it.
The first step is to verify your email and generate an Auth token. This requires only a verifiable email address. Make a POST request to https://web.spin.pm/api/v1/magic_links with the body:
{"email": "sampleemail#gmail.com"}
From there, you will need to find the token within your email. This token needs to be sent with a POST request to
https://web.spin.pm/api/v1/auth_tokens with the body:
{
"grant_type": "magic_link",
"magic_link": {
"email": "<email>",
"token": "<token>"
}
}
This request returns a JSON that looks like this: {"jwt":"eyJ0eXAiOiJ.....cXVLw","refreshToken":"2cb07....bab5030","existingAccount":false}
To get the position of vehicles so a GET-Request to https://web.spin.pm/api/v3/vehicles?lng=-77.0146489&lat=38.8969363&distance=&mode= User Header Authorization: Bearer to Authenticate and use the jwt-Token we got from the Auth request.
You will get something like this as return JSON {"vehicles":[{"lat":37.69247,"lng":-122.46595,"last4":"3595","vehicle_type":"bicycle","batt_percentage":null,"rebalance":null}, … ]}
Step 3 is done using (async/awit function) using fetch where I am having the problem with. I copy-pasted the jwt in my .env file and set up the proper headers.
I get a 401 response when making the call. when I tested step 3 using postman everything seems to work fine.
I have attached a screenshot of the error in this post. Hopefully its more clear, Thanks in advance.
const fetch = require("node-fetch");
require('dotenv').config();
async function getBikes()
{
const lat = '38.897574612438575';
const lng = '-77.01855164084469';
const api_url = `https://web.spin.pm/api/v3/vehicles?lng=${lng}&lat=${lat}&distance=&mode=`;
const jwt_key = process.env.BERER_KEY;
try{
const config = { method: 'GET',
headers: {json: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Bearer'+ jwt_key
} },
rejectUnauthorized: false
};
const response = await fetch(api_url,config );
const data = await response.json(); //response.json() //headers //.jwt; //response.json()
if (response.ok)
{
console.log("STATUS CODE IS: "+response.status);
console.log('My JWT:', response);
return data;
}
else{
console.log("something went wrong ");
console.log("STATUS CODE IS: "+ response.status);
console.log( response);
}
} catch (error) {
console.log(error);
}
}
const y = getBikes();
console.log(y)
BEARER_KEY=eyJhbGciOiJIUzI1NiJ9.eyJ1c2V
I managed to get Reddit OAuth to work and it is getting redirected to my homepage.
And I am getting a URL like http://localhost:3000/?state=XEA12&code=6p4pAyle2EWGVwIBlFJ6ERXjxKg
Now, when I try other APIs like /api/me. I am not able to get it working. I have also set the scope of my app to identity.
Here is the code snippet that I wrote:
import axios from "axios";
import useSWR from "swr";
const link = "https://www.reddit.com/api/v1/me";
const config = {
headers: {
"Content-Type": "application/x-www-form-urlencoded",
Authorization: "bearer 6p4pAyle2EWGVwIBlFJ6ERXjxKg",
},
};
const fetcher = (url) => axios.get(url, config).then((res) => res);
export default function Home() {
const { data, error } = useSWR(link, fetcher);
if (error) return <div>failed to load </div>;
if (!data) return <div>loading...</div>;
return <div>{JSON.stringify(data)}</div>;
}
Can you please tell me what I am doing wrong? Is it because of the headers or do I need to pass something else?
According to the documentation you need to retrieve access_token first, by using code param. Here is how to do that: https://github.com/reddit-archive/reddit/wiki/OAuth2#retrieving-the-access-token
Then you can use that access_token in a bearer auth. There is another note: API requests with a bearer token should be made to https://oauth.reddit.com, NOT www.reddit.com. Hope it will help
I am trying to call an express endpoint with fetch from my react app and pass the body as a JSON object so that I can include more data within it. The call currently works when I set body directly to token.id, but I want to include more data. For now I'm just constructing the JSON with that one piece of data, but cannot seem to get the server to properly handle it. I have the working lines of code commented out, which I know work as I am seeing the calls make it through to the stripe API. With the new code I get as far as the token creation working, but the create customer call does not show up on the stripe API.
import React, {Component} from 'react';
import {CardElement, injectStripe} from 'react-stripe-elements';
class CheckoutForm extends Component {
constructor(props) {
super(props);
this.state = {complete: false};
this.submit = this.submit.bind(this);
}
async submit(ev) {
let {token} = await this.props.stripe.createToken({name: "Name"});
let data ={
id: token.id
}
let response = await fetch("/charge", {
method: "POST",
//Works with the commented code
//headers: {"Content-Type": "text/plain"},
//body: token.id,
headers: {"Content-Type": "application/json"},
body: JSON.stringify(data)
}).then(response => response.json());
if (response.ok) console.log("Purchase Complete!")
if (response.ok) this.setState({complete: true});
}
render() {
if (this.state.complete) return <h1>Purchase Complete</h1>;
return (
<div className="checkout">
<p>Would you like to complete the purchase?</p>
<CardElement />
<button onClick={this.submit}>Send</button>
</div>
);
}
}
export default injectStripe(CheckoutForm);
This is my server code:
const app = require("express")();
const stripe = require("stripe")("sk_test_oE2EqjsM7mWqgRRwaomptrdX");
app.use(require("body-parser").text());
app.post("/charge", jsonParser, async (req, res) => {
try {
var userdata = JSON.parse(req.body);
let {status} = stripe.customers.create({
description: "Test Person",
//Commented code currently works
//source: req.body
//Below is how I expected this to work when passing the body as JSON
source: userdata.id
});
res.json({status});
} catch (err) {
res.status(500).end();
}
});
app.listen(9000, () => console.log("Listening on port 9000"));