So, I'm going to be having a service that posts fields to my app and have to do the following:
When an action occurs within your account, several values are passed
along in the Instant Notification query string (see URL Parameters).
While building the string we create a sha1, or a hash of the values
passed, and your Secret Key. The result is the cverify parameter. Upon
receipt of the query string parameters, your system must also create a
sha1, or a hash of the values passed, and your Secret Key.
The validity of the data received is evaluated by using the cverify
parameter we send and the value produced in your system. Only if there
is an exact match between the two values can you be certain the
information received has not been tampered with.
I'm guessing I should use the crypto module. But, not sure how to do the rest of this. The params would come in via the req.body I know... but, not sure about the rest.
Below is their example from python
import hashlib
##
# Verify cverify from an ipn.
# #param post_params: A dictionary of all POST parameters from the notification
# #return: True if the cverify parameter is valid, false otherwise
def ipnVerification(post_params):
secret_key = "YOUR SECRET KEY"
pop = ""
ipn_fields = []
for key in post_params.keys():
if key == "cverify":
continue
ipn_fields.append(key)
ipn_fields.sort()
for field in ipn_fields:
pop += post_params[field] + "|"
pop += secret_key
return post_params["cverify"] == hashlib.sha1(pop).hexdigest()[:8].upper()
This is what I have so far:
var secretKey = 'My Secret Key';
module.exports = {
validateRequest: function(req){
var params = []
for (param in req.body) {
if (param == "cverify")
continue;
params.push(param);
}
params.sort();
var pop = "";
for (param in params) {
pop += req.body.param + "|";
}
pop += secretKey;
var cverify = req.body.cveryify;
// do crypto stuff
console.log(params);
}
}
If I understand the code correctly:
var secretKey = 'My Secret Key';
module.exports = {
validateRequest : function(req) {
/* shorter version of what you have already:
var keys = Object.keys(req.body)
.filter(function(key) { return key !== 'cverify'; })
.sort();
var pop = keys.map(function(key) {
return body[key];
}).join('|') + '|' + secretKey;
*/
...
var sha1 = require('crypto').createHash('sha1');
sha1.update(pop);
var digest = sha1.digest('hex').substring(0, 8).toUpperCase();
return digest === req.body.cverify;
}
};
Related
I made a python api that I'm trying to get my app to connect to, but for the login function I need to send the username and password but I'm not sure how to do this. This is the python code:
username = data.get('username')
email = data.get('email')
password = data.get('password')
And the Kotlin Code:
private fun sendData(username:String, password:String): Thread {
return Thread {
val url = URL("https://127.0.0.1:5000/login")
val connection = url.openConnection() as HttpsURLConnection
connection.setRequestProperty("username", username)
connection.setRequestProperty("password", password)
if (connection.responseCode == 200) {
val inputSystem = connection.inputStream
println(inputSystem.toString())
Toast.makeText(applicationContext, "It worked", Toast.LENGTH_SHORT).show()
}
else {
var code: String = "ERROR"
Toast.makeText(applicationContext, "NO CONNECTION", Toast.LENGTH_SHORT).show()
}
}
}
The connection is opened but I can get any data across and I haven't tried anything so far as I can't find good documentation on this.
You could, for example, first set up a class to handle your credentials:
class LoginData(
val userID: String,
val pw: String
){
/** Returns a hashmap of the data stored in the class object. */
fun getHashmap(): Map<String,String> {
val params = HashMap<String,String>()
params["username"] = userID
params["password"] = pw
return params
}
/** Obtains a JSONObject of the data stored in the class object. */
fun getJson(): JSONObject {
val params = this.getHashmap()
return JSONObject(params)
}
}
And then, utilising Volley (don't forget to add it to your build gradle: implementation 'com.android.volley:volley:1.2.0'), do something like this:
fun sendData(username: String?, password: String?) {
val url = "https://127.0.0.1:5000/login"
var loginData = LoginData(
userID = username!!,
pw = password!!
)
val queue = Volley.newRequestQueue(this)
val jsonRequest = JsonObjectRequest(
Request.Method.POST,
url,
loginData.getJson(),
Response.Listener {
response -> handleResponse(response)//do something with the response
},
Response.ErrorListener { error -> println("That didn't work: $error")})
queue.add(jsonRequest)
}
with handleResponse() containing your logic to evaluate what comes back from the server:
fun handleResponse(response: JSONObject) {
//your evaluation logic
}
I am trying to send an authentificated message over an API at iconomi.com.
I am used to sign message when dealing with other exchange API, but can't be authentificated with this specific one.
I read the official documentation for authentification:
You generate the ICN-SIGN header by creating a sha512 HMAC using the
base64-decoded secret key on the prehash string timestamp + method +
requestPath + body (where + represents string concatenation) and
base64-encode the output, where:
the timestamp value is the same as the ICN-TIMESTAMP header. the body
is the request body string or omitted if there is no request body
(typically for GET requests). method must always be in upper case
Example: base64_encode(HMAC_SHA512(secret_key, timestamp + upper_case(method) + requestPath + body))
I found also a java client example on the official github, please see bellow signature generation in java :
private String generateServerDigest(String method, String uri, long timestamp, String body) {
//return timestamp + request.getMethodValue() + uri + body;
String checkDigestString = timestamp + method + uri + body;// "GET+/v1/daa-list+123123123"; //timestamp in epoch milliseconds
// hash server composited digest with algorithm and apikeys secret
SecretKeySpec signingKey = new SecretKeySpec(apiSecret.getBytes(), "HmacSHA512");
Mac mac;
try {
mac = Mac.getInstance(signingKey.getAlgorithm());
mac.init(signingKey);
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
log.warn("Could not ={}", signingKey.getAlgorithm());
return null;
}
return Base64.getEncoder().encodeToString(mac.doFinal(checkDigestString.getBytes()));
}
Please note that checkDigestString code timestamp + method + uri + body and comment GET+/v1/daa-list+123123123 are already different on the official doc.
And this is my python implementation attempt :
def sign(timestamp,method,requestPath,body):
global api_secret
base64_decoded_secret_key = base64.b64decode(api_secret)
content_to_hash = (str(timestamp) + method.upper() + requestPath + body).encode('utf-8')
sign_digest = hmac.new(base64_decoded_secret_key, content_to_hash , hashlib.sha512).digest()
return base64.b64encode(sign_digest).decode('utf-8')
When I try this signature method with requestPath = "/v1/user/balance" (which required to be authentificated), it fail without error...
Does any one used with both java and python may help me to convert this signature method to python ?
This code will work for GET:
import time,requests
import hashlib,hmac,base64
api_key = "my api key"
api_secret = "my api secret"
defaut_encoding = "utf8"
uri = "https://api.iconomi.com"
requestPath = "/v1/user/balance"
api_url_target = uri+requestPath # https://api.iconomi.com/v1/user/balance
method="GET"
body=""
icn_timestamp = int(1000.*time.time())
message = (str(icn_timestamp) + method.upper() + requestPath + body).encode(defaut_encoding)
signature_digest = hmac.new(api_secret.encode(defaut_encoding), message, hashlib.sha512).digest() #here digest is byte
b64_signature_digest= base64.b64encode(signature_digest).decode(defaut_encoding)
headers_sign= {
"ICN-API-KEY":api_key,
"ICN-SIGN":b64_signature_digest,
"ICN-TIMESTAMP":str(icn_timestamp)
}
s=requests.session()
res = s.get(api_url_target,headers=headers_sign,timeout=3, verify=True).content
print (res)
Update for #Karl comment, this code will work for POST:
import time,requests
import hashlib,hmac,base64,json
api_key = "my api key"
api_secret = "my api secret"
ticker = "my ticker strategy"
defaut_encoding = "utf8"
uri = "https://api.iconomi.com"
requestPath = "/v1/strategies/"+ticker+"/structure"
api_url_target = uri+requestPath # https://api.iconomi.com/v1/strategies/{my ticker strategy}/structure
method="POST"
body="{'ticker': ticker, 'values': [{'rebalancedWeight': 1., 'targetWeight':1., 'assetTicker': 'XMR', 'assetName': 'Monero', 'assetCategory': 'Privacy'}]}"
icn_timestamp = int(1000.*time.time())
message = (str(icn_timestamp) + method.upper() + requestPath + body).encode(defaut_encoding)
signature_digest = hmac.new(api_secret.encode(defaut_encoding), message, hashlib.sha512).digest() #here digest is byte
b64_signature_digest= base64.b64encode(signature_digest).decode(defaut_encoding)
headers_sign= {
"ICN-API-KEY":api_key,
"ICN-SIGN":b64_signature_digest,
"ICN-TIMESTAMP":str(icn_timestamp)
}
s=requests.session()
res = s.post(api_url_target,headers=headers_sign,json = json.loads(body), timeout=3, verify=True).content
print (res)
I am trying to sign the message in javascript using signMessage and verify it with python for implementing jwt authentication.
This is the code for signing message in javascript using near-api-js
window.signer = await new nearlib.InMemorySigner(window.walletAccount._keyStore)
const mysign = await window.signer.signMessage("Amiya",
window.walletAccount._authData.accountId, window.walletAccount._networkId)
let mypubdata = ""
mysign.publicKey.data.forEach( function (item,index){
if(item < 16) {
mypubdata = mypubdata + '0' + item.toString(16)
}
else {
mypubdata = mypubdata + item.toString(16)
}
})
console.log("public key", mypubdata)
let mysignature = ""
mysign.signature.forEach( function (item,index){
if(item < 16) {
mysignature = mysignature + '0' + item.toString(16)
}
else {
mysignature = mysignature + item.toString(16)
}
})
console.log("signature", mysignature)
Output gives:
public key fe20d3e271876c8329c74dcdbe95e32586ee5cf67def1c0cc9e0b8d0e4285813
signature 61d864f40667075da6f920f811def3b83330a6cce49b7bd24eb4711f29abcf55d6d2eaf6f67bf74f20a2f79598f7fd42b4f70db41446d73d596b58d31825710c
This is my python code for backend:
import ed25519
import hashlib
pubKey = ed25519.VerifyingKey(b"fe20d3e271876c8329c74dcdbe95e32586ee5cf67def1c0cc9e0b8d0e4285813", encoding="hex")
print("Public key (32 bytes): ", pubKey.to_ascii(encoding='hex'))
signature = "61d864f40667075da6f920f811def3b83330a6cce49b7bd24eb4711f29abcf55d6d2eaf6f67bf74f20a2f79598f7fd42b4f70db41446d73d596b58d31825710c"
msg = hashlib.sha256(b"Amiya").hexdigest()
print(msg)
try:
pubKey.verify(signature, msg, encoding='hex')
print("The signature is valid.")
except:
print("Invalid signature!")
But I am unable to make it work, it gives an invalid signature.
Formalizing the answer given by #topaco in the comment above:
Try digest() instead of hexdigest() – Topaco May 27 at 18:13
I'm trying to access the web services of a Moodle installation I have using Python's requests library. I have the API's documentation and an example project written in php (I haven't looked at php before and is way more difficult than I would expect for me to understand) but am really struggling to properly format the request. The site is returning invalid paramater detected so I'm pretty sure my endpoint, authorization token, and server config is working and it's just the format of the data that is letting me down.
First here is the error...
<?xml version="1.0" encoding="UTF-8" ?>
<EXCEPTION class="invalid_parameter_exception">
<ERRORCODE>invalidparameter</ERRORCODE>
<MESSAGE>Invalid parameter value detected</MESSAGE>
</EXCEPTION>
And now my code...
import requests
target = 'http://example.com/moodle/webservice/rest/server.php?'
moodle_create_token = 'xxx'
moodle_enrol_token = 'yyy'
url_payload = {
"wstoken":moodle_create_token,
"wsfunction":"core_user_create_users"
}
###not sure if I should just be passing this as a dict or some deeper more layered struct
payload = {
"username":"testuser",
"password":'testpass',
"firstname":'testf',
"lastname":'testl',
"email":"test#example.com",
"idnumber":"1234"
}
###not sure how to include the payload as the last argument in the function (currently data=)
###I feel like at this point I've just been throwing random data at it and hoping something sticks haha.
r=requests.post(target, params=url_payload, data=payload)
Here is the site's documentation
moodle api general structure
moodle api XML-RPC (PHP structure)
moodle api REST (POST parameters)
moodle response format 1
moodle response format 2
Finally the example in php.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>V6</title>
</head>
<body>
<?php
//load curl.php
require_once('curl.php');
function randomPassword() //according to Moodle password requirements
{
$part1 = "";
$part2 = "";
$part3 = "";
//alphanumeric LOWER
$alphabet = "abcdefghijklmnopqrstuwxyz";
$password_created = array(); //remember to declare $pass as an array
$alphabetLength = strlen($alphabet) - 1; //put the length -1 in cache
for ($i = 0; $i < 3; $i++)
{
$pos = rand(0, $alphabetLength); // rand(int $min , int $max)
$password_created[] = $alphabet[$pos];
}
$part1 = implode($password_created); //turn the array into a string
//echo"<br/>part1 = $part1";
//alphanumeric UPPER
$alphabet = "ABCDEFGHIJKLMNOPQRSTUWXYZ";
$password_created = array(); //remember to declare $pass as an array
$alphabetLength = strlen($alphabet) - 1; //put the length -1 in cache
for ($i = 0; $i < 3; $i++)
{
$pos = rand(0, $alphabetLength); // rand(int $min , int $max)
$password_created[] = $alphabet[$pos];
}
$part2 = implode($password_created); //turn the array into a string
//echo"<br/>part2 = $part2";
//alphanumeric NUMBER
$alphabet = "0123456789";
$password_created = array(); //remember to declare $pass as an array
$alphabetLength = strlen($alphabet) - 1; //put the length -1 in cache
for ($i = 0; $i < 2; $i++)
{
$pos = rand(0, $alphabetLength); // rand(int $min , int $max)
$password_created[] = $alphabet[$pos];
}
$part3 = implode($password_created); //turn the array into a string
//echo"<br/>part3 = $part3";
$password = $part1 . $part2 . $part3 . "#";
return $password;
}
function getCDate()
{
$format = "Ymd";
$fulldate = date($format);
//echo"<br/>fulldate = $fulldate";
return $fulldate;
}
function enrol($user_id, $course_id)
{
$role_id = 5; //assign role to be Student
$domainname = 'http://www.yoursite.eu'; //paste your domain here
$wstoken = '8486ed14f3ghjec8967a0229d0a28zzz'; //here paste your enrol token
$wsfunctionname = 'enrol_manual_enrol_users';
$enrolment = array( 'roleid' => $role_id, 'userid' => $user_id, 'courseid' => $course_id );
$enrolments = array($enrolment);
$params = array( 'enrolments' => $enrolments );
header('Content-Type: text/plain');
$serverurl = $domainname . "/webservice/rest/server.php?wstoken=" . $wstoken . "&wsfunction=" . $wsfunctionname;
$curl = new curl;
$restformat = ($restformat == 'json')?'&moodlewsrestformat=' . $restformat:'';
$resp = $curl->post($serverurl . $restformat, $params);
print_r($resp);
}
function getUserDetails()
{
$firstname = "TestUser";
$lastname = "TestUser";
$email = "TestUser#zzz.gr";
$city = "Thessaloniki";
$country = "EL";
$description= "ZZZ";
//assign username
//get first two letters of name and surname
//$strlength_user = strlen($firstname);
//$strlength_pass = strlen($lastname);
$rest_firstname = substr($firstname, 0, 2);
$rest_lastname = substr($lastname, 0, 2);
$part1 = $rest_firstname . $rest_lastname;
$part1 = strtolower($part1);
//echo"<br/>part1 = $part1";
$dt = getCDate();
$part2 = substr($dt, -4);
//echo"<br/>part2 = $part2";
$username = $part1 . "." . $part2;
echo"<br/>Username = $username";
//assign password
$password = randomPassword();
echo"<br/>Password = $password";
//call WS core_user_create_user of moodle to store the new user
$domainname = 'http://www.yoursite.eu';
$wstoken = 'ed1f6d3ebadg372f95f28cd96bd43zzz'; //here paste your create user token
$wsfunctionname = 'core_user_create_users';
//REST return value
$restformat = 'xml';
//parameters
$user1 = new stdClass();
$user1->username = $username;
$user1->password = $password;
$user1->firstname = $firstname;
$user1->lastname = $lastname;
$user1->email = $email;
$user1->auth = 'manual';
$user1->idnumber = 'numberID';
$user1->lang = 'en';
$user1->city = $city;
$user1->country = $country;
$user1->description = $description;
$users = array($user1);
$params = array('users' => $users);
//REST call
header('Content-Type: text/plain');
$serverurl = $domainname . "/webservice/rest/server.php?wstoken=" . $wstoken . "&wsfunction=" . $wsfunctionname;
$curl = new curl;
$restformat = ($restformat == 'json')?'&moodlewsrestformat=' . $restformat:'';
$resp = $curl->post($serverurl . $restformat, $params);
print_r($resp);\
//get id from $resp
$xml_tree = new SimpleXMLElement($resp);
print_r($xml_tree);
$value = $xml_tree->MULTIPLE->SINGLE->KEY->VALUE;
$user_id = intval(sprintf("%s",$value));
echo"<br/>user_id number = $user_id";
//enrol_manual_enrol_users
//for($i = 64; $i < 70; $i++) //where 64,65,66,67,68,69 are the six ids of the six courses of phase 1
for($i = 64; $i < 65; $i++)
{
echo "\nThe user has been successfully enrolled to course " . $i;
$course_id = $i;
enrol($user_id, $course_id);
}
}
getUserDetails();
?>
</body>
</html>
Here is an example drawn from mrcinv/moodle_api.py that shows the usage of Python's requests to hit the Moodle Web Services API:
from requests import get, post
# Module variables to connect to moodle api
KEY = "SECRET API KEY"
URL = "https://moodle.site.com"
ENDPOINT="/webservice/rest/server.php"
def rest_api_parameters(in_args, prefix='', out_dict=None):
"""Transform dictionary/array structure to a flat dictionary, with key names
defining the structure.
Example usage:
>>> rest_api_parameters({'courses':[{'id':1,'name': 'course1'}]})
{'courses[0][id]':1,
'courses[0][name]':'course1'}
"""
if out_dict==None:
out_dict = {}
if not type(in_args) in (list,dict):
out_dict[prefix] = in_args
return out_dict
if prefix == '':
prefix = prefix + '{0}'
else:
prefix = prefix + '[{0}]'
if type(in_args)==list:
for idx, item in enumerate(in_args):
rest_api_parameters(item, prefix.format(idx), out_dict)
elif type(in_args)==dict:
for key, item in in_args.items():
rest_api_parameters(item, prefix.format(key), out_dict)
return out_dict
def call(fname, **kwargs):
"""Calls moodle API function with function name fname and keyword arguments.
Example:
>>> call_mdl_function('core_course_update_courses',
courses = [{'id': 1, 'fullname': 'My favorite course'}])
"""
parameters = rest_api_parameters(kwargs)
parameters.update({"wstoken": KEY, 'moodlewsrestformat': 'json', "wsfunction": fname})
response = post(URL+ENDPOINT, parameters).json()
if type(response) == dict and response.get('exception'):
raise SystemError("Error calling Moodle API\n", response)
return response
class CourseList():
"""Class for list of all courses in Moodle and order them by id and idnumber."""
def __init__(self):
# TODO fullname atribute is filtered
# (no <span class="multilang" lang="sl">)
courses_data = call('core_course_get_courses')
self.courses = []
for data in courses_data:
self.courses.append(Course(**data))
self.id_dict = {}
self.idnumber_dict = {}
for course in self.courses:
self.id_dict[course.id] = course
if course.idnumber:
self.idnumber_dict[course.idnumber] = course
def __getitem__(self, key):
if 0<= key < len(self.courses):
return self.courses[key]
else:
raise IndexError
def by_id(self, id):
"Return course with given id."
return self.id_dict.get(id)
def by_idnumber(self, idnumber):
"Course with given idnumber"
return self.idnumber_dict.get(idnumber)
def update_courses(courses_to_update, fields):
"Update a list of courses in one go."
if not ('id' in fields):
fields.append('id')
courses = [{k: c.__dict__[k] for k in fields} for c in courses_to_update]
return call("core_course_update_courses",
courses = courses)
.. and also shows how to define custom classes for Course. In the same fashion one could create classes for User, Grades, etc.
Furthermore, there are some wrapper modules on PyPi, e.g. moodle, and moodle-ws-client.
Okay so I found a solution that works but I suspect it is a bit hodgepodge and not utilizing requests library to its fullest.
What I did was pass all the arguments as parameters in the url.
target = 'http://example.com/moodle/webservice/rest/server.php'
moodle_create_token = 'xxx'
payload = {
"wstoken":moodle_create_token,
"moodlewsrestformat":"json", #just to get response as json
"wsfunction":"core_user_create_users",
"users[0][username]":"testusername",
"users[0][password]":'testpassword',
"users[0][firstname]":'testfirstname',
"users[0][lastname]":'testlastname',
"users[0][email]":"testemail#example.com",
"users[0][idnumber]":"0000001"
}
r=requests.post(target, params=payload)
Obviously I won't usually have the data hard-coded as strings but apparently the list of dictionaries for url params will be.
I have made a python library named moodlepy
pip install moodlepy
Its easy to use, example
from moodle import Moodle
target = 'http://example.com/moodle/webservice/rest/server.php'
moodle_create_token = 'xxx'
moodle = Moodle(target, moodle_create_token)
r = moodle(
'core_user_create_users',
username="testusername",
password='testpassword',
firstname='testfirstname',
lastname='testlastname',
email="testemail#example.com",
idnumber="0000001"
) # return the data (dict, list, etc)
You can also use typed response, for example calling core_webservice_get_site_info
site_info = moodle.core.webservice.get_site_info()
site_info.username
site_info.version
Note: Not all functions are implemented (yet).
I am trying to replicate the following lines of python code from the https://github.com/joshfraser/robinhood-to-csv repo from GitHub in order to read my transaction history.
orders = robinhood.get_endpoint('orders')
paginated = True
page = 0
while paginated:
for i, order in enumerate(orders['results']):
executions = order['executions']
instrument = robinhood.get_custom_endpoint(order['instrument'])
fields[i + (page * 100)]['symbol'] = instrument['symbol']
for key, value in enumerate(order):
if value != "executions":
fields[i + (page * 100)][value] = order[value]
if order['state'] == "filled":
trade_count += 1
for key, value in enumerate(executions[0]):
fields[i + (page * 100)][value] = executions[0][value]
elif order['state'] == "queued":
queued_count += 1
# paginate
if orders['next'] is not None:
page = page + 1
orders = robinhood.get_custom_endpoint(str(orders['next']))
else:
paginated = False
Where we also have
def get_endpoint(self, endpoint=None):
res = self.session.get(self.endpoints[endpoint])
return json.loads(res.content.decode('utf-8'))
I have thus been working on the following iOS code. I work with this code in an XCode playground so feel free to make one to follow along
import UIKit
import PlaygroundSupport
let LoginEndpoint:String = "https://api.robinhood.com/api-token-auth/"
let LoginRequestData:[String : String] = ["username": "EmailAdress", "password": "Password"]
let OrdersEndpoint:String = "https://api.robinhood.com/orders/"
func httpReq(type: String, url: String, body:[String : String], header:[String : String]) -> ([String : Any]?, Data?, String?){
let url = URL(string: url)
var returnData:([String : Any]?, Data?, String?)? = nil
if let url = url {
var request = NSMutableURLRequest(url: url) as URLRequest
request.httpMethod = type
var postString = ""
for (key, value) in body {
if (postString != "") {
postString += "&"
}
postString += "\(key)=\(value)"
}
request.httpBody = postString.data(using: .utf8)
for (key, value) in header {
request.addValue(value, forHTTPHeaderField: key)
}
let _ = URLSession.shared.dataTask(with: request, completionHandler: {(data, response, error) in
if let data = data {
do {
let jsonSerialized = try JSONSerialization.jsonObject(with: data, options: []) as? [String : Any]
returnData = (jsonSerialized, data, nil)
} catch (_) {
returnData = (nil, data, "JSON Parse Erro")
}
} else if let error = error {
returnData = (nil, nil, error.localizedDescription)
}
}).resume()
}
while (returnData == nil) {}
return returnData!
}
let tokenQuery = httpReq(type: "POST", url: LoginEndpoint, body: LoginRequestData, header: [:])
if let token = tokenQuery.0?["token"] {
print("token \(token)")
let historyQuery = httpReq(type: "GET", url: OrdersEndpoint, body: [:], header: ["Authorization": "Token \(token)"])
if let results = historyQuery.0?["results"], let countString = historyQuery.0?["count"] {
}
}
RunLoop.main.run()
PlaygroundPage.current.needsIndefiniteExecution = true
So as you can see I am using the auth token to get to the orders endpoint. I am indeed getting a good response from the orders endpoint but I have no clue how to interpret it.
It would seem from the python code that it is returning an array of JSON objects however I cant figure out how to get to that array in swift. I am not even sure if I am decoding it properly. The funny thing is when you look at the object returned in Playgrounds it would seem XCode knows that there is an array going on. How do I get to it?
Can't really get a good idea of the information being returned by your service, because of the lack of credentials.
However, check out SwiftyJSON. It's a really good library, and is extremely helpful with handling JSON data in Swift. It should solve your JSON handling issues.