I tried to get the ebay user token.
I've alreay gotten auth code in ebay, but can't get user token with auth code.
Code is following:
status := ctx.UserValue("status").(string)
applicationToken := string(ctx.QueryArgs().Peek("code"))
log.Println("ApplicationToken: ", applicationToken)
log.Println("Status: ", status)
if status == "declined" {
fmt.Printf("User doesn't give permission. Go back to your dashboard.")
ctx.Redirect("/dashboard", fasthttp.StatusSeeOther)
}
//var appConfig = config.Config()
client := &http.Client{}
applicationTokenURLEncoded, _ := url.Parse(applicationToken)
body := url.Values{
"grant_type": {"authorization_code"},
"code": {applicationTokenURLEncoded.String()},
"redirect_uri": {Runame},
}
reqBody := bytes.NewBufferString(body.Encode())
log.Println("Reqbody: ", reqBody)
req, _ := http.NewRequest("POST", "https://api.sandbox.ebay.com/identity/v1/oauth2/token", reqBody)
authorization := “AppID” + ":" + “CertID”
authorizationBase64 := base64.StdEncoding.EncodeToString([]byte(authorization))
req.Header.Add("Authorization", "Basic "+authorizationBase64)
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
log.Println("Body: ", req)
resp, _ := client.Do(req)
log.Println("resp: ", resp)
log.Println("ResBody: ", resp.Body)
And the error is like that:
Bad Request 400
I looks like the message isn't formed correctly (which is why the server returns 400).
When you're setting your headers you write:
req.Header.Add("Authorization", "Basic "+authorizationBase64)
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
Golang has a nice built in way to add Authorization to a Header: SetBasicAuth, which is a method of http.Request.
func (r *Request) SetBasicAuth(username, password string)
SetBasicAuth sets the request's Authorization header to use HTTP Basic Authentication with the provided username and password.
With HTTP Basic Authentication the provided username and password are not encrypted.
So instead of setting the Authorization Header manually, you could try:
req.SetBasicAuth("AppID”, “CertID”)
You were using something called CertID, but I think you meant ClientId and ClientSecret -- respectively user and password
I don't know if this is the cause of your problem :). One way to help find out, is consistent error checking, see your line:
applicationTokenURLEncoded, _ := url.Parse(applicationToken)
Related
I have been trying to to implement a FIX Client in Go to interact with FTX. To send the initial logon message, FTX's API doc asks the client to include a signature in the message.
In the return message from the FTX, it says "Invalid signature".
Below is my implementation for generating the signature:
func signatureGenerator(msgType, msgSeqNum, senderCompID, targetCompID string) string {
timeNow := time.Now().UTC().Format("20060102-15:04:05")
message := [][]byte{[]byte(timeNow),
[]byte(msgType),
[]byte(msgSeqNum),
[]byte(senderCompID),
[]byte(targetCompID)}
SOH := []byte{0x01}
signature := bytes.Join(message, SOH)
signSha256 := hmac.New(sha256.New, []byte(userInfo.CLIENT_API_SECRET))
signSha256.Write(signature)
strSig := hex.EncodeToString(signSha256.Sum(nil))
return strSig
}
I am trying to create a charge in Stripe following API documentation but without success :
jsnObj := TJSONObject.Create;
jsnObj.AddPair('amount', TJSONNumber.Create('111'));
jsnObj.AddPair('currency', 'eur');
jsnObj.AddPair('customer', 'cus_JL30ptApR3U2gL');
jsnObj.AddPair('description', 'My First Test');
ss := TStringStream.Create(jsnObj.ToString);
rs := TStringStream.Create;
IdHTTP1.Request.BasicAuthentication := True;
IdHTTP1.Request.Username := ApiKey ; // test private key
IdHTTP1.Post('https://api.stripe.com/v1/charges', ss, rs);
StatusBar1.SimpleText := IdHTTP1.ResponseText;
the result is always error :
{
"error": {
"code": "parameter_missing",
"doc_url": "https://stripe.com/docs/error-codes/parameter-missing",
"message": "Must provide source or customer.",
"type": "invalid_request_error"
}
}
Http returns 400 bad request.
All data is correct but the source parameter is missing as Stripe documentation states that it is optional so I include customer parameter instead and it should work.
Other calls to the Stripe API are successful with the same code (connect, retrieve objects etc.)
Thanks for any tips..
I was playing with this was able to get it working immediately using Node/Javascript, took a while using Golang (this is just generating the user/password to be sent to coturn.) Notice the secret should match the coturn configuration and in the API JS/Go side.
The configuration on coturn: /etc/turnserver.conf
listening-port=443
tls-listening-port=443
listening-ip=10.100.0.2
relay-ip=10.100.0.2
external-ip=123.456.78.9
min-port=10000
max-port=20000
verbose
fingerprint
lt-cred-mech
server-name=myserver
realm=myserver
cert=/etc/SSL/fullchain.pem
pkey=/etc/SSL/privkey.pem
log-file=/var/log/turnserver.log
use-auth-secret
static-auth-secret=MySecret
The following is Node/Js Implementation API (copied from elsewhere - worked):
var crypto = require('crypto');
var unixTimeStamp = parseInt(Date.now()/1000) + 24*3600, // this credential valid for 24 hours
TempUser = [unixTimeStamp, "SomeUser"].join(':'),
TempPassword,
hmac = crypto.createHmac('sha1', "MySecret");
hmac.setEncoding('base64');
hmac.write(TempUser);
hmac.end();
TempPassword = hmac.read();
The following is GOLANG Implementation API (took a while):
UserId := "SomeUser"
// This worked, returned the exact seconds
timestamp := strconv.FormatInt(time.Now().UTC().Unix()+24*3600, 10)
// Example: The above is 1602692130
secret := "MySecret"
TempUser := timestamp + ":" + UserId // For API Auth, coturn expects this format, the timestamp is the expiry date of the final temp user/password.
// Create a new HMAC by defining the hash type and the key (as byte array)
//h := hmac.New(sha256.New, []byte(secret)) // sha256 does not work, use sha1
h := hmac.New(sha1.New, []byte(secret))
h.Write([]byte(TempUser))
//sha := b64.URLEncoding.EncodeToString(h.Sum(nil)) // URLEncoding did not work
TempPassword := b64.StdEncoding.EncodeToString(h.Sum(nil)) // StdEncoding worked
The JS on the Webrtc client. Notice we are using the TempUser and TempPassword here to be sent to coturn.
...
const stunUrl = 'stun:mystun_server',
turnUsername = TempUser,
turnPassword = TempPassword,
...
'iceServers': [
{ 'url': stunUrl },
{
'urls': turnUrl1,
'username': turnUsername,
'credential': turnPassword
},
Now coturn will authenticate using the TempUser and TempPassword above. Hope someone will find this useful. Thanks!
I am developing an API in Golang (with Buffalo library).
I have my route set to point to :
func (ur UserResource) Create(c buffalo.Context) error {
// new User
u := &models.User{}
if err := c.Bind(u); err != nil {
return c.Render(500, r.String(err.Error()))
}
id, _ := uuid.NewV4()
u.ID = id
db[u.ID] = *u
return c.Render(201, r.JSON(u))
}
The problem is that when I test my api I have the following error :
(and my header Content-Type is set to multipart/form-data)
If I change the way values are passed to form-url-encoded and set no header, I have this error :
invalid character 'i' in literal false (expecting 'a')
I'm doing a simple rest API which does the following:
get base64 encoded image
decode it
stores it on on specific google bucket
Now, on the GET verb, my api returns a signed url targeting the bucket image.
I've coded a test that works:
initialization stuff
...
BeforeEach(func() {
mockStringGenerator.On("GenerateUuid").Return("image1")
// First store
image, _ = ioutil.ReadFile("test_data/DSCF6458.JPG")
encodedImage = b64.RawStdEncoding.EncodeToString(image)
fileName, storeError = storage.Store(ctx, encodedImage, "image/jpeg")
// Then get
uri, getError = storage.Get(ctx, fileName)
getResponse, _ = http.Get(uri)
// Finally delete
deleteError = storage.Delete(ctx, fileName)
})
// Only 1 test to avoid making too much connexion
It("should create, get and delete the image", func() {
// Store
Expect(storeError).To(BeNil())
Expect(fileName).To(Equal("image1.jpg"))
// Get
Expect(getError).To(BeNil())
Expect(getResponse.StatusCode).To(Equal(http.StatusOK))
b, _ := ioutil.ReadAll(getResponse.Body)
Expect(b).To(Equal(image))
// Delete
Expect(deleteError).To(BeNil())
})
But when I run the .exe and try to make ssome request with postman, I get a 403 error in the signed url:
<?xml version='1.0' encoding='UTF-8'?>
<Error>
<Code>AccessDenied</Code>
<Message>Access denied.</Message>
<Details>Anonymous caller does not have storage.objects.get access to teddycare-images/08d8c508-d97d-48d3-947b-a7f216f622db.jpg.</Details>
</Error>
Any ideas ? I really don't understand...
Save me guys
[EDIT] Here after the code I use to create signedUrl:
func (s *GoogleStorage) Get(ctx context.Context, fileName string) (string, error) {
url, err := storage.SignedURL(s.Config.BucketImagesName, fileName, &storage.SignedURLOptions{
GoogleAccessID: s.Config.BucketServiceAccountDetails.ClientEmail,
PrivateKey: []byte(s.Config.BucketServiceAccountDetails.PrivateKey),
Method: http.MethodGet,
Expires: time.Now().Add(time.Second * 180),
})
if err != nil {
return "", err
}
return url, nil
}
Ok, after I woke up, I found the answer.
It turns out that when the json is marshalized into string, all the special characters are encoded.
Example: & -> \u0026
So the url I tested in my UT had &, while the url returned by the api had \u0026, and google does not seem to have the same behaviour on both cases.
So the solution is to disable HTML escaping:
encoder := json.NewEncoder(w)
encoder.SetEscapeHTML(false)
return encoder.Encode(response)