React Native and Stripe Integration 401 Error - react-native

I am new to React Native and Stripe API and have been trying to integrate the two for my payments module. So initially when I used the code as node.js docs described I'm getting an error because of HTTP module that is not available in React Native.
Until I encountered this blog describing a workaround using the Fetch API instead of the usual Stripe implementation. But when I run my code I am getting a 401 error which means Unauthorized or the key is invalid. Considering that my implementation and key is correct, what could be causing this error? Here's a sample code:
fetch('https://api.stripe.com/v1/customers', {
method: 'post',
headers: {
'Accept': 'application/json',
'Authorization': 'Bearer MY_TEST_KEY'
},
body: JSON.stringify({
firstName: 'John',
lastName: 'Doe'
})
})
Thanks in advance!

Unfortunately, it's not possible to do any of this in your mobile application as those calls require your Secret API key. You should never have the Secret API key in your mobile application otherwise an attacker could get his hands on it and then create charges, refunds or transfers on your behalf.
What you need to do here is create a card token first in your mobile application. You then send it to your server where you will create the charge or the customer using your Secret key.

Related

securing stripe secret key with server side

I am just trying to understand how to securely store the stripe secret key.
For sure I should not have it hardcoded on the app.
I am seeing in most tutorials secret value is saved in the server. Then it's retrieved to make call. Can't this be just be simply intercepted?
To make a request like this. This need a secret to passed in. I am using the amplify graphql.
var response = await http.post(Uri.parse('https://api.stripe.com/v1/payment_intents'), body: body, headers: {
'Authorization': 'Bearer sk_test_51JtrW7EI6WXcFFnPxSxwCIm24D8Gjj3e6hzxch4009kFOsXo7',
'Content-Type': 'application/x-www-form-urlencoded'
});
I am seeing in most tutorials secret value is saved in the server. Then it's retrieved to make call.
Most Stripe tutorials show the client-side/webpage/mobile-apps fetching the publishable key from your server. That key is (by design) public.
That approach helps especially with mobile apps where you cannot dynamically update your publishable key, you need to go through a full App Store review to get a new version of your app out, but fetching it from your server allows you to easily update a publishable key if needed.

Xero Authentication in WordPress

I have a client that wants to be able to create xero invoices from a custom backend plugin that I have created in WordPress. I understand the xero api docs and what data to pass to the api to create a new invoice but I have to somehow authenticate the user so that they can send data to the api. So far I have created my xero app with a client id and client secret which I believe is required to help authenticate the api request.
But how can I authenticate the api request?
If I do simple request like this it fails:
jQuery(document).ready(function ($) {
$.ajax({
url: 'https://api.xero.com/connections',
error = (res) => {
console.log(res);
},
success = (res) => {
console.log(res);
}
});
});
I'd first recommend using the official xero PHP sdk, however I'm not sure if you are able to import packages to Wordpress like this. I've done some wordpress but I know there are some limitations with importing certain external libraries.
https://github.com/XeroAPI/xero-php-oauth2
However as an alternate solution, theres a recent blogpost on using a raw OAuth2.0 library to connect to XeroAPI manually though. This might set you on the right direction!
https://medium.com/#sid.maestre/use-php-to-connect-with-xero-31945bccd037

React Native App keeps on returning Network Request failed error with the Fetch method

I have a WAMP server on my localhost, and I'm trying to run the php file inside of it, through my react native app in order to store user information. I know I needed to use my localhost's IPv4, and the port number, then the file location, but I still keep on getting: 'Possible Unhandled Promise Rejection (id: 0): TypeError: Network Request failed', while running my app on an ios device on the expo app.
I've tried making it an https instead of http, but i still keep on getting the same error, I've copy pasted the link into google chrome and it runs the php file, but when i do it on another device on the same network, it takes a very long time to connect but then it times out right away, and yes, my server is online.
fetch('http://[My server's IPv4 address]:80/Fetcher/Users.php', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
username: this.state.username,
password: this.state.password,
})
}).then((response) => {response.json()}).then(fullResponse => {
console.warn(fullResponse);
console.warn('out');
}).catch(err => console.error(err));
I expected it to take in the username and password and store them on the table I created on my WAMP server's table under the schema I've created.
What happens instead is I get a Network request failed error on my app
It looks like you are facing the same issue as in this post.
By default Android & iOS are blocking cleartext HTTP resource loading. You'll need to enable it both on iOS and Android as described in the post.
Using https in this case won't work because you do not have a valid server certificate.
Also check the same post for possible other sources of this issue.

UnauthorizedError: jwt malformed error when authenticating

Im using Auth0 for authenticating users for my react application.I have been trying to access resources on server side but I keep getting UnauthorizedError: jwt malformed as an Error.
I’ve followed a the following thread on the community forums: https://community.auth0.com/t/unauthorizederror-jwt-malformed-in-express-js/7352
Many users have suggested that the audience value from the guide is wrong. The audience given in the guide is https:///userinfo but it should be ‘https://.auth0.com/api/v2/’, I’ve made that change and the error is still there.
This has worked for some people but not for me.
This is the guide ive been following: https://auth0.com/blog/react-tutorial-building-and-securing-your-first-app/
const checkJwt = jwt({
secret: jwksRsa.expressJwtSecret({
cache: true,
rateLimit: true,
jwksRequestsPerMinute: 5,
jwksUri: `https://<domain>/.well-known/jwks.json`
}),
// Validate the audience and the issuer.
audience: "https://<something>/api/v2/",
issuer: `https://<something>/`,
algorithms: ["RS256"]
});
this is the code ive written on the express side.
this.auth0 = new auth0.WebAuth({
// the following three lines MUST be updated
domain: "<Domain>",
audience: "https://<Something>/api/v2/",
clientID: "clientID",
redirectUri: "http://localhost:3000/callback",
responseType: "token",
scope: "openid"
});
This is the code written on the frontend of the application.
One of our senior engineers had a good recommendation on this that I will share below:
If you haven't done so already you should perform these steps:
capture the token you receive; for example, using a console.log statement given this is in development.
review the captured token; does it look like a JWT?
if its a JWT and you can parse it at jwt.io then update the API to log the received token before trying to validate it; does the received
token match the one you expect?
In conclusion, try to take steps that allow you to gather a bit more
of information.

Keycloak API always returns 401

I'm trying to interact with Keycloak via its REST API. I have the master realm and the default admin user, and a test realm. Firstly, I get an access token for the admin account and test realm:
let data = {
grant_type : 'password',
client_id : 'test-realm',
username : 'admin',
password : 'admin'
};
let headers = {
'Content-Type': 'application/x-www-form-urlencoded'
};
axios.post(
'https://someurl.com:8080/auth/realms/master/protocol/openid-connect/token',
qs.stringify(data),
headers
)
That works ok. Then I try to make a call to create a user (or do anything else) and I get a 401 unauthorized error:
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': `Bearer ${accessToken}`
};
data = {
rep: {
email: "test#email.com",
username: "test#email.com"
},
path: 'test-realm'
};
axios.post('https://someurl.com:8080/auth/admin/realms/test-realm/users',
qs.stringify(data),
headers
)
Is that not the correct way to include the token? Is the access token the one you use for authenticating other API calls? Shouldn't the admin account's token work for authenticating calls to other clients with the master realm? Would it be some setting in the master realm that I have to change in the admin console? Any help appreciated.
I got a 401 error because I generated the offline token by using http://localhost:8080 and then I tried to request the api by using http://keycloak:8080 which is not allowed. Unfortunately the log doesn't tell you that.
To debug JWT tokens I recommend https://jwt.io/
Is that not the correct way to include the token?
This is a correct way.
You just do something incorrectly.
Please, refer for an example from keycloak-request-token Node.js module:
https://github.com/keycloak/keycloak-request-token/blob/master/index.js#L43
You use
client_id : 'test-realm'
but there is
client_id: 'admin-cli'
there.
Also, to create a user, you should use
'Content-Type': 'application/json'
You can refer for Node.js examples of Keycloak REST API here:
https://github.com/v-ladynev/keycloak-nodejs-example/blob/master/lib/adminClient.js
Examples of other useful stuff like:
custom login
storing Keycloak token in the cookies
centralized permission middleware
can be found in the same project: keycloak-nodejs-example
I fixed it by enabling the below "Service Accounts Enabled" button under Settings for admin-cli
I had this issue and solved it by making sure that there is no more than 1 minute between the first and the second API request. So, if you are doing this manually (2 curl requests), the token may expire and you may get error 401. Nevertheless, you should use admin-cli as mentioned above.
I came this issue recently and after struggling for a while i figured. using a realm name containing white spaces will trigger 401 unauthorized error when interacting with via SDKs or API.
IN SUMMARY:
change: realm name
to: realm-name