I need to implement xsolla payment solution into my CakePHP 2.6 webapp.
By contract my site should communicate via REST with Xsolla.
Every request should contain Authorization Signature header which is sha1 hash of JSON body and the secret token.
Where is the right place to check Signature from xsolla in cakePHP?
Example request from xsolla:
URL: http://example.com/rest
Accept: application/json
Content-Type: application/json
Content-Length: 78
Authorization: Signature 8189119fb35327cdee7787990df41001c4bd9122
{"data":{"notification_type":"user_validation","user":{"id":"user_id"}}}
I need to check Authorization: Signature
The correct way of handling this in CakePHP is to implement a custom authorization handler. See the following links for reference, they explain what you need to do in great detail.
The basic procedure is to read the auth header and compare it against the user in your database. You'll do that in your custom authorization handler.
CakePHP 2.x
Authorization
Creating custom authorization handlers
CakePHP 3.x
Authorization
Creating custom authorization handlers
JWT Token Auth (check the code for reference)
The JWT auth is basically exactly doing what you want. The auth adapters aren't that much different. So you can backport that to CakePHP 2.x
Related
I need to get an OAuth token using a simple POST request.
In Postman, we configure OAuth tokens via the following configuration:
When I click "Get New Access Token", postman makes a request against the Access Token URL.
How does one see what that request looks like? Are these parameters (client id, client secret, etc.) placed in a POST body? What are the headers? I'd like to see the request structure in plain text.
Essentially I need to emulate this request in a script, where I have to include the credentials in the body itself, where the body would look something like this:
{
"Access_Token_URL":"myURL",
"Client_ID":"myClientId",
"Client_Secret":"myClientSecret",
"Scope":"myScope"
}
That request follows the OAuth 2.0 specification, using the client_credentials grant, and it will use an Authorization Basic header to authenticate the client; so its body will look like this:
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic bXlDbGllbnRJZDpteUNsaWVudFNlY3JldA
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&scope=MyScope
Where bXlDbGllbnRJZDpteUNsaWVudFNlY3JldA is the Base64-encoded value of myClientId:myClientSecret.
Note that the Content-Type is application/x-www-form-urlencoded.
Also note that what Postman calls the Access Token URL is actually named Token Endpoint in the OAuth 2.0 terminology.
I'm in "Integration Request". I've set HTTP integration type and the Endpoint URL.
Below, I see "HTTP Headers, but if I try to add an header, there is a strange "mapped from" value I don't understand.
Setting an HTTP Proxy integration add a Mapping template I also don't understand.
I just need to pass the Authorization:xxxx and X-Auth-Username:xxxxx from the original request to the endpoint
Can't find an easy way...
I set HTTP proxy integration and added in the HTTP Headers (and deployed):
method.request.header.Authorization
method.request.header.X-Auth-Username
I also added as required Authoriaxtion and X-Auth-Username in Method request header as required.
But I get an error upon calling the api:
Authorization header requires 'Credential' parameter.
Authorization header requires 'Signature' parameter.
Authorization header requires 'SignedHeaders' parameter.
Authorization header requires existence of either a 'X-Amz-Date' or a 'Date' header
Hmmm maybe it's a "naming" problem?
So I changed "authorization" with MyAuthentication in the method request, and after in the integration Header, I mapped Authorization to
method.request.header.MyAuthentication
Now if I call my api with MyAuthorization in the header, I get "Missing Authentication Token", without hitting the api server
Click on 'Method Request' , expand 'HTTP Request Headers' and add a header Authorization . Now go back and click on 'Integration Request' , expand 'HTTP Headers' and add Header Name Authorization and 'Mapped from' method.request.header.Authorization . Basically for any header XYZ on 'Method Request' tab should have corresponding mapping on 'Integration Request' method.request.header.XYZ .
To Correctly use aws API Gateway as a pure http proxy and make it pass the Authorization header as-is to your backend API, you need to do two things:
In the Method Request: Make sure to add the Authorization header to the Http Request Headers section.
With this, AWS does not assume that the Authorization header is of your own implementation and the gateway does not expect it to contain AWS own format of multiple parameters such as SignedHeaders, Signature, X-Amz-Date , etc..
2. In the Integration Request: Make sure to select the Use HTTP Proxy Integration.
This makes sure that the request is being sent to the target as-is and thus the Authorization header not to be consumed and discarded as part of AWS own SigV4 authorization.
The following was correct...I was calling the original api path instead of te api gateway path....
I set HTTP proxy integration and added in the HTTP Headers (and deployed):
method.request.header.Authorization
method.request.header.X-Auth-Username
URL :
https://circuitsandbox.net/rest/v2/webhooks
My Headers :
Content-Type : application/x-www-form-urlencoded
Authorization : Bearer ot-xxxxxxxxxxxx
Body :
url - Some URl
filter - CONVERSATION.CREATE
Error I am getting :
"The permission to access this resource is not granted. Scopes ::= [ALL, READ_CONVERSATIONS, READ_USER]"
Plus If i want to send extra filters thn will it be comma separated values?
If you are getting a 403, I would suspect a scope error (as mentioned by Roger) or an authentication problem.
For the first, please show us which scopes are currently selected for the application ; for authentication, can you check if you can make other API calls successfully ?
Here is what it looks like in Postman
Make sure your app registration contains the scopes that your app is asking for. For a simple outgoing webhook registration you would only need the scope READ_CONVERSATIONS.
See https://github.com/circuit/circuit-REST-bot/blob/master/app.js for an example on how to register for a webhook. This example registers for CONVERSATION.ADD, but CONVERSATION.CREATE is very similar.
If you still have problems please post a code example, or even a link to an app on repl.it.
Here is an example HTTP request to register the webhook. Note that the body is sent as text/plain (which is the default and its header can be omitted). Also note that the callback url is http. https is not yet supported.
POST https://circuitsandbox.net/rest/v2/webhooks HTTP/1.1
Host: circuitsandbox.net
Content-Type: text/plain
Authorization: Bearer <token>
url=http://90587c6d.ngrok.io/webhook&filter=CONVERSATION.CREATE
and here is a curl command
curl -X POST https://circuitsandbox.net/rest/v2/webhooks -H "Authorization: Bearer <token>" -d "url=http://90587c6d.ngrok.io/webhook&filter=CONVERSATION.CREATE"
It's the first time for me to try to get a REST call to work thru POST from Firefox. I generated the token and the Auth strings needed as follows:
oauth_consumer_key
oauth_nonce
oauth_signature
oauth_signature_method
oauth_timestamp
oauth_token
Does the order meter? Because I can't understand if I'm missing anything else. Here is my Request
https://api.twitter.com/1.1/search/tweets.json?q=&geocode=30.0444,31.2357,1km&until=2013-11-30&result_type=mixed&oauth_consumer_key=0xxxQ&oauth_nonce=bcbcxxx8&oauth_signature=pXXXglKjY%3D&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1390221337&oauth_token=2287933520-fuxxxR0&count=100
The Response is:
401 Unouthorized
{"errors":[{"message":"Could not authenticate you","code":32}]}
Could anyone help please?
Thanks,
EDIT 1
As Mike suggested the Console, it actually does work from the console, but the console asks you to login so it manages the authorization, which is fine
Now that I know my request works, how to add these parameters to an $.ajax call? I tried adding the following:
beforeSend : function(req) {
req.setRequestHeader('Authorization', auth);
},
where "auth" is the "OAuth oauth_consumer_key=..." but I get a bad request error 400.
Ideas anyone?
Thanks,
Per Twitter's authorizing a request page, you need to pass in your oAuth parameters via the Authorization header, not in the query parameters.
Example given on that page (put all of the OAuth fields on the same line, no newlines):
POST /1/statuses/update.json?include_entities=true HTTP/1.1
Accept: */*
Connection: close
User-Agent: OAuth gem v0.4.4
Content-Type: application/x-www-form-urlencoded
Authorization:
OAuth oauth_consumer_key="xvz1evFS4wEEPTGEFPHBog",
oauth_nonce="kYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg",
oauth_signature="tnnArxj06cWHq44gCs1OSKk%2FjLY%3D",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1318622958",
oauth_token="370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb",
oauth_version="1.0"
Content-Length: 76
Host: api.twitter.com
status=Hello%20Ladies%20%2b%20Gentlemen%2c%20a%20signed%20OAuth%20request%21
Another gotcha. It turns out the default .NET implementation of UrlEncode outputs the percent encoding in lower case. Looks like Twitter expects lowercase encoding, returning a 401 when parameters are lower case.
Here's some code to fix that up:
.net UrlEncode - lowercase problem
I have been using FB api for some simple demo and everything was quite easy with the authentication. Now I have to do something similar with twitter v1.1 but there is something that I really don't understand...
Example:
I want to do this request:
https://api.twitter.com/1.1/search/tweets.json?q=q=%23freebandnames
the problem is that I have to be authenticated, anyone have some examples? I don't want to create a twitter connection because I don't need different users to be connected to my applicaiton. I have just to perform some simple search request but I can't understand how to use the authentication parameters. Which type of Ajax request I have to use in order to perform the REST request authenticated??? (Obviously I have my secret token and my access secret token) but how to use them????
THanks in advance for answers
You can use this javascript library: codebird-js with the "Application-only auth".
or
Do it yourself: everything is explained in the documentation.
Basically you need to follow 3 steps (and you should do the 2 first just once):
An application encodes its consumer key and secret into a specially encoded set of credentials.
An application makes a request to the POST oauth2/token endpoint to exchange these credentials for a bearer token.
When accessing the REST API, the application uses the bearer token to authenticate.
The steps are detailed in the documentation.
You can do the first 2 separately and when you get your bearer token, you need to add a specific HTTP Header (Authorization) in each request with your bearer token (that's the 3rd step). With jQuery it could be something like that:
$.ajax({
headers: { Authorization: 'Bearer '+$my_bearer_token },
url: 'https://api.twitter.com/1.1/search/tweets.json?q='+$search
}).done(function (data) {
// Play with the data
});