I am trying to implement Paypal webhooks and everything is working fine except the webhook signature verification. I have read a dozen of posts here on stackoverflow and I still can not figure out what my mistake is, because no matter what I do it always returns { verification_status: "FAILURE" }.
For example here Paypal webhook verification fails everytime one of the posts suggests that this is because the payments are in Sandbox mode. I tried a real actual payment with Live keys, Live environment and so on, it still failed.
https://developer.paypal.com/docs/api/webhooks/v1/#verify-webhook-signature_post this is the endpoint that I am trying to use, and here is what I am doing:
When paypal sends the request to my webhook route, first I am generating the auth token:
const params = new URLSearchParams()
params.append('grant_type', 'client_credentials')
const getAuthToken = await axios.post(
'https://api-m.sandbox.paypal.com/v1/oauth2/token',
params,
{
headers: { 'content-type': 'application/x-www-form-urlencoded' },
auth: {
username: 'usernametoken',
password: 'passwordtoken',
},
},
)
Then I use the token along with the headers received from the initial Paypal request to try to verify the webhook:
const verifyWebhook = await axios.post('https://api-m.sandbox.paypal.com/v1/notifications/verify-webhook-signature', {
auth_algo: req.headers['paypal-auth-algo'],
cert_url: req.headers['paypal-cert-url'],
transmission_id: req.headers['paypal-transmission-id'],
transmission_sig: req.headers['paypal-transmission-sig'],
transmission_time: req.headers['paypal-transmission-time'],
webhook_id: 'webhookID as generated in the developer portal',
webhook_event: req.body.resource,
}, {
headers: {
Authorization: `Bearer ${getAuthToken.data.access_token}`,
},
})
console.log(verifyWebhook.data); // this is always { verification_status: "FAILURE" } even with a REAL transaction
Related
Hello everyone it is been 6 hours I am struggling to solve this issue.
I have the following projects:
Client App: ReactJS using axios library
Server App: .NET Core Web api implementing JWT for authorization and authentication.
The Problem:
when trying to send get request from my react application using axios to the backend and attaching the jwt in the header I always get 401 unauthorized.
I tried the same way using postman It works perfectly !!!!!!!!!!
My attempts:
I tried to add the cors to my api and allows every origin, every header, every method still did not work.
Sending Request From ReactJS using axios:
async function getAllUserTasks() {
try {
return axios({
method: "get",
url: "http://localhost:5133/todo/ToDos",
headers: {
Authorization: `Bearer ${localStorage.getItem("jwtToken")}`,
},
body: {
userId: JSON.stringify('924BF80F-F394-4927-8DCC-A7B67AFA663C')
},
});
} catch (error) {
console.log(error);
}
}
//call the function one time
useEffect(() => {
getAllUserTasks();
}, []);
My config for the JWT in .NET app:
services.AddAuthentication(defaultScheme: JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options => options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = jwtSettings.Issuer,
ValidAudience = jwtSettings.Audience,
IssuerSigningKey = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(jwtSettings.Secret))
});
My config for policy and cors:
services.AddCors(o => o.AddPolicy("MyPolicy", builder =>
{
builder.WithOrigins("http://localhost:3000", "http://localhost:3000/")
.AllowAnyMethod()
.AllowAnyHeader();
}));
This is really frustrating!
Try post request and also get the token from local storage outside of request definition. I think one of theese will fix your problem.
I've been working on a React/Spring project with the ambition of better understanding spring security and while going fairly successful thus far I've found a shortage of information relating to the handling of CSRF tokens between React and Spring boot. As such, I'm at an impasse.
My question is: How do you add and authenticate a CSRF token between React and Spring Boot on POST requests?
So far I've managed to get the CSRF token into my Cookies (thanks spring) and from there, I've attempted accessing the CSRF token and adding it to my HTTP headers although still receiving 403 responses on POST requests.
My spring security config class contains the declaration enabling CSRF outside of http(withHttpOnlyFalse() ).
How I'm trying to access the CSRF token:
I found this online previously for accessing the cookie:
function getCookie(name) {
if (!document.cookie) {
return null;
}
const xsrfCookies = document.cookie.split(';')
.map(c => c.trim())
.filter(c => c.startsWith(name + '='));
if (xsrfCookies.length === 0) {
return null;
}
return decodeURIComponent(xsrfCookies[0].split('=')[1]);
}
How I'm declaring HTTP headers:
let csrfToken = getCookie("XSRF-TOKEN");
console.log("testing csrf token: " + csrfToken);
const res = await fetch(`/register`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-CSRF-TOKEN": csrfToken,
},
body: JSON.stringify({
firstName: firstName,
lastName: lastName,
mobileNumber: mobileNumber,
email: email,
password: password,
}),
});
Any help/support is greatly appreciated.
I've managed to resolve this.
Considering the difficulty I had sourcing information here's my solution:
Install the react-cookies library (npm install react-cookies)
Inside of the component which triggers the POST request, declare the following:
const cookies = useCookies(['XSRF-TOKEN']);
Pass 'cookies' to your function which facilitates the fetch request - For me this was simply called 'signUp' and was called inside my handleSubmit() method.
const handleSubmit = (event) => {
event.preventDefault();
const data = new FormData(event.currentTarget);
signUp(data.get("firstName"), data.get("mobileNumber"), data.get("email"),
data.get("password"), setUser, cookies['XSRF-TOKEN'] );
}
My fetch request inside of signUp() looks like the following:
await fetch(`/register`, {
headers: {
"X-XSRF-TOKEN": token,
"Content-Type": 'application/json'
},
credentials: 'include',
method: "POST",
body: JSON.stringify(customerData),
});
I'm sure this isn't the cleanest, nor the most practical way to do this and I hope someone is willing to shed further clarity if this is the case.
This was posted on the basis that I struggled to find a solution and hope this may be of some use/help going forwards.
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.
I want to patch the user_metadata of a user in my Auth0 Authentication in react native but I get the following error:
{"error": "Unauthorized", "message": "Missing authentication", "statusCode": 401}
So I am importing Auth0 in my react native:
import Auth0 from "react-native-auth0";
const auth0 = new Auth0({
domain: Config.AUTH0_DOMAIN,
clientId: Config.AUTH0_CLIENT_ID
});
I use the constants Config.AUTH0_DOMAIN and Config.AUTH0_CLIENT_ID from my dashboard from my application.
As a next step I execute the following code:
login = () => {
auth0.webAuth
.authorize({
scope: Config.AUTHO_SCOPE,
audience: Config.AUTH0_AUDIENCE,
device: DeviceInfo.getUniqueID(),
prompt: "login"
})
.then(res => {
auth0.auth
.userInfo({token: res.accessToken})
.then(data => {
fetch(`https://<MY_AUTH_DOMAIN>/api/v2/users/${encodeURIComponent(data.sub)}`, {
method: "PATCH",
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
"metadata": {first_name: 'John', last_name: 'Doe', skillLevel: 'PRO!'}
})
}).then(res => res.json())
.then(async (data) => {
try {
console.log('user stored', data);
} catch (e) {
console.log("error while user storing", e)
}
})
})
})
}
Whereby Config.AUTHO_SCOPE and Config.AUTH0_AUDIENCE is also from my auth0's app dashboard.
Am I missing some authentication in my headers or is the Management API the wrong choice? Do I need to to this query probably from my Back-End?
Resources:
Official API Doc from the Management API: https://auth0.com/docs/api/management/v2?_ga=2.147997749.368915485.1617866251-2089752765.1617460658#!/Users/patch_users_by_id
Official react-native-auth0 doc: https://auth0.github.io/react-native-auth0/src_management_users.js.html
Thanks for the help!
I was having this issue and I got it working after a little work.
First, I had to configure my project to give metadata write permission in Auth0's dashboard at Applications/Apis.
The two I added were read:current_user and update:current_user_metadata.
Then, in my authorize request, I modified both scope and audience.
audience: 'https://<MY APP DOMAIN>/api/v2/'
scope: 'read:current_user update:current_user_metadata openid profile offline_access'
Next, I got the userId by passing my authentication token to auth.userInfo like so.
auth0.auth.userInfo({token: authToken}).then((response)=>{
return response.sub;
})
Finally, I used the value returned from response.sub along with the authToken that I had setup with special audience and scope to patch the user, and it worked successfully. UserId is what response.sub returned.
auth0.users(authToken).patchUser({id: userId, metadata: newUserMetadata});
EDIT:
One other issue I see with your code snippet, if you want to use fetch, is you didn't put a bearer authorization token in the header. Your fetch response will probably return with a 401 error if that's the case. The code should look something like this:
const serverResponse = await fetch('https://<MYAPP>.auth0.com/api/v2/users/' + user.sub,{
headers:{
Authorization: 'Bearer ' + accessToken
}
})
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);