I finished developing my application with Next.js.
I used Next Auth to handle user authentication.
I use the Credential Provider for authentication with email and password.
In development everything works fine when I log in the session is well created and a JWT token is well generated.
On the other hand when putting in production it does not work, I have the following error:
[next-auth][error][CLIENT_FETCH_ERROR]
https://next-auth.js.org/errors#client_fetch_error invalid json response body at https://my-site.fr/api/auth/csrf reason: Unexpected token < in JSON at position 0 {
I really don't understand why the error only appears in production.
Here is the code of my Credential Provider
CredentialProvider({
async authorize(credentials, req) {
// console.log(credentials);
const url = `${process.env.NEXT_PUBLIC_API}/auth/login`;
const res = await fetch(url, {
method: "POST",
body: JSON.stringify(credentials),
headers: {
"Content-Type": "application/json",
Accept: "application/json, text/plain, */*'",
"User-Agent": "*",
},
});
// console.log(res);
const user = await res.json(res);
if (res.ok && user) {
return user;
}
return null;
},
}),
Thanks for your help.
Related
I working on intergrating a react app with the zendesk api for creating support tickets.
Till now i have completed the form flow, but when i making the request to the zendesk api i am getting 401.
I am using the api_key approach for this.
I am fairly new to zendesk, if anyone can help me regarding that.
Here is my code after user clicks submit.
const onSubmit = async () => {
try {
console.log('setInfo', info)
const data = { request: { subject: 'test', comment: { body: 'testdesc' } } }
const user = 'test#test.com'
const api_token = 'some_api_key'
const url = 'https://url.zendesk.com/api/v2/tickets.json'
const response = await fetch(url, {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
mode: 'no-cors',
headers: {
'Content-Type': 'application/json',
Authorization: api_token,
// 'Content-Type': 'application/x-www-form-urlencoded',
},
body: JSON.stringify(data), // body data type must match "Content-Type" header
})
console.log('respone', response)
} catch (error) {
console.log('respone error', error)
}
}
It looks like you're not sending the right authorization header. According to Zendesk API reference you need to use the following format for the credentials:
{email_address}/token:{api_token}
Example:
jdoe#example.com/token:6wiIBWbGkBMo1mRDMuVwkw1EPsNkeUj95PIz2akv
After base64-encoding the resulting string, add it to the Authorization header as follows:
Authorization: Basic amRvZUBleGFtcGxlLmNvbS90b2tlbjo2d2lJQldiR2tCTW8xbVJETXVWd2t3MUVQc05rZVVqOTVQSXoyYWt2
This Netlify function should run as an endpoint on example.com/.netlify/functions/github and is supposed to proxy a fetch request from my website, reach out to the GitHub API and send data back to the website.
As far as I have understood, I can use to GET data from the GitHub API without authentication. Hitting their API directly in the browser works: https://api.github.com/orgs/github/repos?per_page=2 (also works from Postman).
The data is an array of objects where each object is a repository.
There has been multiple issues the past couple of years where Netlify functions (running on AWS lambdas) have had hickups that resulted in error messages similar to mine, so I'm confused whether this is an error in my code or something weird on their side.
First, the proxy function which – according to the Netlify admin console – runs without error. In a support article Netlify requires the result returned as JSON.stringify(), so I follow that convention here:
const fetch = require('node-fetch')
const url = 'https://api.github.com/orgs/github/repos?per_page=2'
const optionsHeaders = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Content-Type'
}
const fetchHeaders = {
'Content-Type': 'application/json',
'Host': 'api.github.com',
'Accept': 'application/vnd.github.v3+json',
'Accept-Encoding': 'gzip, deflate, br'
}
exports.handler = async (event, context) => {
if (event.httpMethod === 'OPTIONS') {
return {
'statusCode': '200',
'headers': optionsHeaders,
}
} else {
try {
const response = await fetch(url, {
method: 'GET',
headers: fetchHeaders
})
const data = await response.json()
console.log(JSON.stringify({ data }))
return {
statusCode: 200,
body: JSON.stringify({ data })
}
} catch (err) {
console.log(err)
}
}
}
Client fetch that hits https://example.com/.netlify/functions/github. URL is correct, the function is executed (verified that in the Netlify admin panel):
const repos = document.querySelectorAll('.repo')
if (repos && repos.length >= 1) {
const getRepos = async (url) => {
try {
const response = await fetch(url, {
method: "GET",
mode: "no-cors"
})
const res = await response.text()
// assuming res is now _text_ as per `JSON.stringify` but neither
// that nor `.json()` work
console.log(res[0].name)
return res[0].name
} catch(err) {
console.log(err)
}
}
const repoName = getRepo('https://example.com/.netlify/functions/github')
repos.forEach((el) => {
el.innerText = repoName
})
}
Not 100% sure where this error message originates from, it is probably not the console.log(err) although it displays in the browser console, because the error code is 502 and the error also shows up directly in the response body in Postman.
error decoding lambda response: error decoding lambda response: json: cannot unmarshal
string into Go value of type struct { StatusCode int "json:\"statusCode\""; Headers
map[string]interface {} "json:\"headers\""; MultiValueHeaders map[string][]interface {}
"json:\"multiValueHeaders\""; Body string "json:\"body\""; IsBase64Encoded bool
"json:\"isBase64Encoded,omitempty\""; Metadata *functions.Metadata
"json:\"metadata,omitempty\"" }
Haven't found any clear information on this issue, could any of you enlighten me?
The only response that don't comply with the schema is the preflight request. From the error message, I assume you need to change:
'statusCode': '200',
to
'statusCode': 200, // StatusCode int
Even better, because there's no content, you may want to use 204 instead.
If that's still not enough, I may still want to include the body there as well, as it doesn't seem optional:
return {
'statusCode': 204,
'headers': optionsHeaders,
'body': ''
}
*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'm developing a React app that uses the Spotify API I can't figure out why I'm getting this error when trying to get an access token with the API's PKCE OAuth flow.
{
error: "unsupported_grant_type",
error_description: "grant_type parameter is missing"
}
I'm following the directions from the guide exactly and I'm able to obtain an auth code just fine. Here's my call trying to get the token.
let res = await axios.post("https://accounts.spotify.com/api/token", {}, {
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
params: {
"grant_type": "authorization_code",
"code": data.code,
"redirect_uri": redirectUri,
"code_verifier": verifier,
"client_id": clientId
}
}).catch(err => console.error(err));
I've tried passing the params in the body of the post request and as url params and both produce the same results. As you can see, I'm clearly providing a grant_type and I'm using the value that the guide said to use.
I've tried every method I was able to find on the internet, nothing seemed to be working, but after a few hours, this succeeded:
const headers = {
Authorization:
'Basic ' +
new Buffer(CLIENT_ID + ':' + CLIENT_SECRET).toString('base64'),
}
const { data } = await axios.post(
'https://accounts.spotify.com/api/token',
'grant_type=client_credentials',
headers: { headers },
)
this.token = data.access_token
After this, you can simply use any endpoint as seen in the Spotify API examples.
Use querystring npm package to parse the data since we're using application/x-www-form-urlencoded in the header
And change the grant_type to grant_type: "client_credentials"
var querystring = require('querystring');
const headers = {
headers: {
"Content-Type": "application/x-www-form-urlencoded",
}
};
let data = {
grant_type: "client_credentials",
code: data.code,
redirectUri: "http://localhost:8000/callback",
client_id: your_client_id,
client_secret: your_client_secret,
};
we use query.stringify() for the data because the content type is application/x-www-form-urlencoded also don't use params since its a post request
axios
.post(
"https://accounts.spotify.com/api/token",
querystring.stringify(data),
headers
)
.then((response) => {
console.log(response);
})
.catch((error) => {
console.log(error);
});
This works for me:
const headers = {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization:
'Basic ' +
Buffer.from(this.clientId + ':' + this.clientSecret).toString('base64'),
};
this.http.post(
'https://accounts.spotify.com/api/token',
'grant_type=client_credentials',
{ headers },
).subscribe(data => {
console.log(data);
});
I have the same issue, and it's resolved with stringfying request body data
const requestAccessToken = ({
code,
grantType = "authorization_code",
redirectUri = `${APP_BASE_URL}/callback`,
}) => {
const data = qs.stringify({ //query-string library
code,
grant_type: "client_credentials",
redirect_uri: redirectUri,
});
return axios.post(
[SPOTIFY_ACCOUNTS_BASE_URL, SPOTIFY_ACCOUNTS_TOKEN_URI].join(""),
data,
{
headers: {
Authorization: `Basic ${Buffer.from(
`${SPOTIFY_CLIENT_ID}:${SPOTIFY_CLIENT_SECRET}`,
).toString("base64")}`,
"Content-Type": "application/x-www-form-urlencoded",
},
},
);
};
Have you traced the message and verified that the request body is definitely as expected? Your OAuth fields look totally correct so I suspect this could just be an axios syntax issue.
I could be wrong but should the 'params' field be called 'data' instead, as in this class of mine.
Using feedlys api with a node wrapper suggested from feedly to access its api. I am not getting successful logins. I have scoured the docs and any resources available and cannot find any answers so I'm reaching out to the stack overflow community to see if anyone has had experience with this platform.
I tried clearing the cache. I've tried using the fetch api instead of using the node wrapper I am trying to implement.
I installed the node package 'feedly'.
added this code to my server:
const Feedly = require('feedly')
const f = new Feedly({
client_id: 'client_id here',
client_secret: 'client_secret here',
base: 'https://cloud.feedly.com/v3/collections/',
port: 8080
})
async function feedlyStream() {
const results = await f.reads()
return console.log('results', results)
}
feedlyStream();
It does take me to a page to log in, presumably this is the auth so then i can retrieve data.
I'm not a backend user and primarily front end so performing the task this way is new to me.
When i run nodemon ./server.js from the console, it takes me to a login page, like that of feedlys website but then I get the error 'session expired'. There is no other errors, not in the console etc.
I can get retrieve information when working with insomnia to test the api endpoints, with the same exact info as above plus a bearer token.
Here is the fetch version i have tried with is very similar to that of the insomnia input.
const URL = 'https://cloud.feedly.com/v3/collections/'
const proxyurl = "https://cors-anywhere.herokuapp.com/";
window.onload = () => {
fetch(proxyurl + URL, {
credentials: 'same-origin',
Accept: 'application/json',
headers:
{
'Authorization': 'Bearer TOKEN GOES HERE',
'Access-Control-Allow-Origin': 'include',
'Content-Type': 'application/json',
"client_id": "client_id here",
"method": "GET",
"client_secret": "client_secret here",
}
})
.then(function (data) {
console.log('data from api', data.body);
const here = document.getElementById("here")
const bodyText = () => {
if (data.body == null) {
return "Nope, it's null"
}
return data.body;
}
here.innerHTML = bodyText();
})
}
This is what i receive from the console log above
data from api ReadableStreamlocked: false__proto__: ReadableStream
Any help will be greatly appreciated. Thank you.
quite simply i was missing part of the fetch. I needed to transform the response into JSON. Not use to fetch or apis still and this was an obvious but annoying one.
"method": "GET",
"client_secret": "client_secret here",
}
})
.then(res => res.json();) // this is what i needed to add in :)
.then(function (data) {
console.log('data from api', data.body);