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.
Related
According to the Vue docs, I can store environment variables in .env files and they are loaded automatically. This works fine but this page says to not store any sensitive ENV variables in these files since they are bundled with the build.
WARNING
Do not store any secrets (such as private API keys) in your app!
Environment variables are embedded into the build, meaning anyone can
view them by inspecting your app's files.
https://cli.vuejs.org/guide/mode-and-env.html#environment-variables
So, if I am developing a webapp that talks to an API that requires an ID and a secret to be sent in order to get a token, where am I supposed to store these ENV variables (CLIENT_ID, CLIENT_SECRET)?
Locally I have an .env.local file that contains these values and I'm also defining them in the Netlify env variables.
Anything secret should be stored only on your server. It should never be part of your Vue app source code no matter how well you think you've hidden it, or encrypted it.
Generally speaking, you should have the user send their username/password, create a token on the server (look into JSON Web Tokens for a lightweight approach) and then either (1) Set it as an HttpOnly cookie (one that javascript cannot touch) or store it in localStorage on the client and set it as a common header in axios (using headers: { Authorization: 'Bearer ' } is fairly common.
Now, the client should be sending back that JWT with every request. So on your server, you can check the JWT is valid, and if so, send back the data requested.
I try to understand how I can store secrets in a xamarin forms project.
I have a web api core as a backend and a xamarin forms app as a frontend.
I am trying to code facebook authentication with Xamarin.Auth and I need to pass secret key to my app..
My thinking:
Store in the frontend: I could create a config file and encrypt it but the decryption will be in my source code and by decompiling and reflexion the hacker could retrieve the decryption source code and decrypt the secret key.
2: Store in the backend: I could store the keys in the backend but by sniffing requests sent a hacker could retrieve my secret keys.
Then what is the solution? How can I do it?
Thanks,
You could store your secret using Xamarin.Essentials. For Android your secret will be stored in the Androids KeyStore and within the Keychain in the case of iOS. Even if you decide to go with an encrypted config file I would strongly recommend storing your keys and IV in the SecureStorage instead of hard coding it in your source code. It is extremely easy to use and, well, as secure as it gets on a mobile device.
try
{
// write secret
await SecureStorage.SetAsync("oauth_token", "secret-oauth-token-value");
// read secret
var token = await SecureStorage.GetAsync("oauth_token");
}
catch(Exception ex)
{
}
I'm using the site https://www.hurl.it/#top to make a POST HTTP request to the Poloniex Exchange API.
Note that I have generated my Sign by going to https://www.freeformatter.com/hmac-generator.html#ad-output putting my SECRET and API_KEY into the given fields, and choosing the SHA512 algorithm.
I have filled out the fields at https://www.hurl.it/#top with the following (All fields are verbatim other than API_KEY and SECRET for obvious reasons):
Destination
POST: https://poloniex.com/tradingApi
Headers
Key: API_KEY
Sign: SECRET
Parameters
nonce: 0001
command: returnBalances
I am then given the error:
{"error":"Invalid API key\/secret pair."}
What am I doing wrong? Am I not following the API requirements for an HTTP request verbatim? Also I am not looking for any libraries/programming languages to use. I am looking to make this work using this website or something similar, because once I do, I will have what I'm looking for.
Note that I have generated my Sign by going to https://www.freeformatter.com/hmac-generator.html#ad-output putting my SECRET and API_KEY into the given fields, and choosing the SHA512 algorithm.
Api & secret are very sensitive data, so take care to:
- Never share your api key and secret on a tier website. (it could be store and be reuse)
- Never send a request containing your api key and secret in clear. (it could be intercepted by a MIM attack and/or your ISP and/or DPI)
Finally :
You may compute yourself (locally) the signature using a PHP wrapper recommended on the Poloniex Api documentation page
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
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.