I am reading from the Stripe documentation that I can charge an user with the following curl request:
Definition
POST https://api.stripe.com/v1/charges
Request
curl https://api.stripe.com/v1/charges \
-u sk_test_PjPAEVD1LXfUuA6XylJPnQX4: \
-d amount=400 \
-d currency=eur \
-d source=tok_16ffrPHW84OuTX9VFTYguruR \
-d description="Charge for test#example.com"
In an Angular setting, I presume that I have to use $http. However, how do you pass on the parameters?
I tried the following
$http.post('https://api.stripe.com/v1/charges', result)
.success(function(data, status, headers, config) {
alert("success", data);
})
.error(function(data, status, headers, config) {
alert("error", data);
});
but received the error:
XMLHttpRequest cannot load https://api.stripe.com/v1/charges. No
'Access-Control-Allow-Origin' header is present on the requested
resource.
You need to have some code running server-side (perhaps using PHP, Ruby, Node.JS, ASP.NET, etc etc etc) that takes the token you generated in the browser/Javascript as input, and sends it to https://api.stripe.com/v1/charges to make the charge.
You must not make that call from the front-end (browser) Javascript/Angular. By doing so, you are putting your secret key out in public – your Stripe account would no longer be secure. The only key that should ever feature in your front-end code is the public key, which can only be used for making tokens.
Take a look here for instructions on generating the token and sending it to the server, and here for instructions on creating the charge server-side.
Related
I am trying to integrate Yammer API in my Vue.JS project, for Http calls I am using Vue-Resource plugin. While making GET Http call to get posts from Yammer it gives me following error -
Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource.
I tried postman tool and that gives successful response, but when I try to run the same thing in my Vue.JS project using Vue-Resource plugin it wont work.
The Vue.JS code snippet -
function(){
this.$http.get("https://www.yammer.com/api/v1/messages/my_feed.json").then((data)=>{
console.log(data);
});
In main.vue file i have -
Vue.http.interceptors.push((request, next) => {
request.headers.set('Authorization', 'Bearer my_yammer_token')
request.headers.set('Accept', '*/*')
next()
})
Then I tried the code snippets provided by Postman tool for jquery, that too not working.
jQuery code -
var settings = {
"url": "https://www.yammer.com/api/v1/messages/my_feed.json",
"method": "GET",
"timeout": 0,
"headers": {
"Authorization": "Bearer my_yammer_token",
"Cookie": "yamtrak_id=some_token; _session=some_token"
},
};
$.ajax(settings).done(function (response) {
console.log(response);
});
Though, I found similar questions but nothing worked for me.
I am working this to resolve from last 2 days but getting failed again and again. Please guide/help me.
A browser has higher security requirements than a request in PostMan. In a browser, you are only allowed to make XHR requests to your own current host (combination of domain + port) but not to other remote hosts. To nevertheless make a request to a remote host, you can use the browser built-in CORS. By using this, your browser makes a pre-flight request to the remote host to ask if the current page is allowed to request from that host. This is done via the Access-Control response headers. In your case, this header is probably missing or not allowing your page to access, which is why the request does not go through. Please read further into that topic.
However, in your case, using CORS probably won't be a solution for two reasons: To use CORS, the remote host must present a header which allows every requesting host (*) or your specific one. If you cannot set that setting anywhere on the remote host, it won't work. Second, it is not safe to place your authorization token into client-side JavaScript code. Everybody can just read your JS code and extract the authorization token. For that reason, you usually make the actual API call from the server-side and then pass the data to the client. You can use your own authentication/authorization against your server and then use the static authorization key on the server to request the data from the remote host. In that case, you'll never expose the authorization key to your user. Also, on the server-side, you do not have to deal with CORS as it works just like PostMan or curl as opposed to a browser.
I have a REST endpoint called myEndpoint that I can successfully hit using Curl like this:
curl \
--request DELETE \
--header "Content-Type: application/json" \
--header "Authorization: JWT eyJhbFciOiJ__FAKE__sInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InNhcWliIi__FAKE__9pZCI6NSwiZW1haWwiOiJzYXFpYi5hbGkuNzVAZ21haWwuY29tIiwiZXhwIjoxNDkxNzkyMzEzfQ.feGiXm__FAKE__ZS6V-OROM7EzekRzpu_5pwi865tz8" \
--data '{
"myAttribute": "Something"
}' \
"http://localhost:3999/api/myEndpoint"
However, when my AngularJS code tries to call the same endpoint it fails saying that the mandatory myAttribute parameter was not provided. This is how angularJS is making the call:
var httpParams = {'myAttribute': 'Something'};
$scope.myPromise = $http.delete('http://localhost:3999/api/myEndpoint', httpParams).then(self.myEndpointSuccess, self.myEndpointFailure);
(AngularJS's attachment of the JWT token to the HTTP request is not shown, but I'm sure that is working)
How can I see exactly what HTTP request AngularJS is sending so that I can do an apples-to-apples comparison agains my working curl call?
Here is my Chrome's Developer Tools -> Network tab. I don't see the information I'm seeking there:
The $ http service documentation says that $ http.delete gets two parameters, URL and config. By its call curl, I understand that myAtribute is the name given to a parameter that you want to send to the endpoint, in which case it should be in the params property or data property of the config object.
angular reference
another question
FYI, DELETE requests do not typically have a request body.
As for your issue, RTFM; the second arg to $http.delete should be a config object, so in your case
$http.delete('http://localhost:3999/api/myEndpoint', {data: httpParams})
AngularJS provides the $http module for http requests. You can make a specific request with this module and then process the request with the . then() whichever takes a success callback followed by a error callback
I was able to get the sessionToken using username and password. But, after that I want to create the session using POST call as follows in AngularJS. The angular (entire web app) is hosted on AWS S3.
var session_data = { 'sessionToken' : My_session_Token};
$http({
method: 'POST',
url: 'https://myorg.okta.com/api/v1/sessions',
data: session_data,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
}
}).then(function(response) {
console.log(response);
});
The error I am getting is
XMLHttpRequest cannot load https://myorg.okta.com/api/v1/sessions. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://s3.amazonaws.com' is therefore not allowed access.
I have already added the CORS Allow origin header in Okta as well as S3 bucket.
When I try doing the following through terminal
curl -v -X POST \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"sessionToken": "my_session_Token"
}' "https://myorg.okta.com/api/v1/sessions"
First time I get
{"errorCode":"E0000005","errorSummary":"Invalid session","errorLink":"E0000005","errorId":"oaefADOnPONTDidUZYyrVc5rQ","errorCauses":[]}MAC-S014568:~
second time, because of sessionToken is one time use only I get following error
{"errorCode":"E0000004","errorSummary":"Authentication failed","errorLink":"E0000004","errorId":"oaeI-KKSO-iRGSR1gmyUjBS8g","errorCauses":[]}MAC-S01
I don't think the problem is because of the CORS header (Allow origin) as I have already added the origin.
Also, I cannot use SSWS {api_TOKEN} as my application is in angular and its risky to expose the api token.
Any help will be highly appreciated
Okta doesn't support POSTing to /api/v1/sessions to set a cookie in the browser. For a simple use case, you can use the redirect flow:
window.location = 'https://myorg.okta.com/login/sessionCookieRedirect?token={sessionToken}&redirectUrl={redirectUrl}';
All the allowed methods of setting a cookie using a sessionToken are listed here: http://developer.okta.com/use_cases/authentication/session_cookie
I'm stuck in security issue, We have using authentication for API's and calling api from client application using ajax. To brake authentication we have passing our base 64 encoded value in header, but it's visible in my script page. So anyone can access my api's using this encoded value.
please help me to hide and use this header value.
var data={};
var setHeader = { 'Authorization': **'Basic QVBJVXNlcjpwYXNzd29yZA=='** }
$http.post(url, data, {
headers: setHeader
})
.success(function (data, status, headers, config) {
callback(data);
})
.error(function (data, status, headers, config) {
})
If you are using "Token"you could consider provide your Authorization "Token" only after authentication and have the connection between client and server using HTTPS, and never rely on base64 for security.
A very simple example of how could work for a Single Page Application Rest API:
User enter credentials in client app.
Client app send credentials to server under HTTPS in header.
Server return to client a "Token" with expiration time.
Client store "Token" in localStorage (or other methods).
Any subsequent request to API is done using the "Token" passed in header.
When the "Token" expires, client app need to re-authorize asking credentials to User and getting a new valid "Token" from API.
In this way, the client application store only a valid "Token" and not the real credentials. You could potentially add additional validation logic at server side in order to validate even further your "Token" (like IP validation and so on).
Notes: do not relay on Base64 for security as it is not useful for encryption. What it does is just encoding, so it is way of representing binary data using only printable (text) characters.
I am making a Chrome Extension that talks to a website via an api. I want it to pass information about a current tab to my website via a cors request.
I have a POST api request already working. It looks like this:
...
var url = "https://webiste.com/api/v1/users/sendInfo"
...
xhr.send(JSON.stringify({user_name:user_name, password:password, info:info}));
Its corresponding curl statement is something like this:
curl -X POST https://website.com/api/v1/users/sendInfo -d '{ username:"username", password:"password", info: "Lot's of info" }' --header "Content-type: application/json
But, this is not as secure as we want. I was told to mirror the curl command below:
curl --basic -u username:password <request url> -d '{ "info": "Lot's of info" }'
But, one cannot just write curl into javascript.
If someone could either supply javascript that acts like this curl statement or explain exactly what is going on in that basic option of the curl script I think that I could progress from there.
The curl command is setting a basic Authorization header. This can be done in JavaScript like
var url = "https://webiste.com/api/v1/users/sendInfo",
username = "...",
password = "...";
xhr.open('POST', url, true, username, password);
xhr.send(...);
This encodes the username/password using base 64, and sets the Authorization header.
Edit As arcyqwerty mentioned, this is no more secure than sending username/password in the request body JSON. The advantage of using the basic authentication approach is that it's a standard way of specifying user credentials which integrates well with many back-ends. If you need security, make sure to send your data over HTTPS.
curl is the curl binary which fetches URLs.
--basic tells curl to use "HTTP Basic Authentication"
-u username:password tells curl supply a given username/password for the authentication. This authentication information is base64 encoded in the request. Note the emphasis on encoded which is different from encrypted. HTTP basic auth is not secure (although it can be made more secure by using an HTTPS channel)
-d tells curl to send the following as the data for the request
You may be able to specify HTTP basic authentication in your request by making the request to https://username:password#website.com/api/v1/users/sendInfo