"Missing Authentication Token" Error when calling DVLA MOT history API with Postman - rest

Note - I am very much new to all this. Apologies if anything is unclear.
My overriding aim is to pull out MOT history data for a large batch of vehicles from the DVLA API. I understand that this can be done using Postman, which I am using (on a 64-bit Windows laptop if at all relevant).
The DVLA provide the following instructions
====================================================
Getting started
All API interfaces are implemented as restful APIs and accessed over https.
To access API you will need an API key that uniquely identifies the source of the request. DVSA will give you an API key if it approves your application.
You should keep your API key secure, as DVSA manages throttling and quotas at an API key level.
Each request must have the following mandatory fields in the header:
Accept: application/json+v6
x-api-key:
Content-type field confirms that the response type is in JSON format, and the x-api-key field serves your API key to identify the source of the request.
Technical resources
Access the API at https://beta.check-mot.service.gov.uk/
This root URL will change when the service moves from beta to live.
These 4 endpoints equate to the 4 methods of using the API:
/trade/vehicles/mot-tests?registration={registration}
‘Registration’ is the vehicle registration number.
===================================================
In order to test that this is possible, I am entering the following single request into the bar in Postman, selecting "POST" and hitting "SEND"
https://beta.check-mot.service.gov.uk/trade/vehicles/mot-tests?Content-type=application/json&x-api-key=ABCDEFGH&registration=MYREG
n.b. no inverted commas or other punctuation surrounds the actual values for ABCDEFH or MYREG
Expected result: Some sort of JSON with MOT history for this vehicle
Actual result: {"message": "Missing Authentication Token"}{"message": "Missing Authentication Token"}
I am unclear on:
- whether I should be using POST
what the +v6 after the application is necessary (other documentation leaves it out)
Why "Accept" and "Content-type" appear to be used interchangeably in the documentation
Whether the ordering of the parameters matters
Whether this can be equally tested by simply pasting the url into a browser
Thanks for any help

Reading through the Documentation found here:
https://dvsa.github.io/mot-history-api-documentation/
It mentions that those fields should be added as Headers:
Each request must have the following mandatory fields in
the header:
- Accept: application/json+v6
- x-api-key: <your api key>
There are example cURL requests on the site to help you with creating the request.
If you use Postman's Import feature within the app (found in the top right), you can add this cURL request in the Paste Raw Text tab.
curl -H "Accept: application/json+v6" -H "x-api-key: <your_api_key>" https://beta.check-mot.service.gov.uk/trade/vehicles/mot-tests\?registration=ZZ99ABC
This will give you an example request of what it should look like. From here, you will be able to add in your own API Token and send the request.

If you are using Postman, you can use the Authorization tab right under the request to give the required mandatory header fields. Select Header from Add to drop down. You can also add additional headers information using the next tab named Headers. (for example, the accept-headers).
Edit:
Authorization:
Headers Tab
Normally, you should be getting the authorization token when you register to the site in question(x-api-key here).You need to figure out the value of that token from the initial call's response headers. According to the document which Danny shared, you will be getting x-api-key from them once they approve your request.
Edit:
Alternatively, you can use import feature as Danny suggested in his answer. At the end of the day, you need to add the values as headers instead of query parameters.

For anyone using Python with the MOT history api and getting the same error message, try GET:
import requests
url = f'https://beta.check-mot.service.gov.uk/trade/vehicles/mot-tests?registration={plate_number}'
payload = {}
headers = {
'Accept': 'application/json+v6',
'x-api-key': 'your-api-key'}
response = requests.get(url, headers=headers, data=payload)
data = response.json()
model = data[0]['model'] # get the vehicle model for example
print(model)

Related

Generate API signature in request header from parameters in the request body

I'm using OWASP ZAP to test our API. We have a couple of POST endpoints which use an API Token and a shared secret for authentication and validating the request.
Some parameters of the request body are concatenated and hashed using the shared secret. This value is inserted into the request header.
How can I programatically generate this signature using OWASP ZAP?
Request Header
Content-Type: "application/json"
Accept: "application/json"
API-Key: {API_KEY}
Signature: {hash(field_one + field_two + field_three + SHARED_SECRET)}
Request Body
{
"field_one": "abc",
"field_two": "123",
"field_three": "xyz"
}
The SHARED_SECRET is the password that is stored locally by the client and used to hash the three fields from the request.
It is stored on the server along with the API-Key so that requests can be identified and validated.
Use an HTTP Sender Script. Create it in the ZAP UI so that you can test it as you're writing it. First make sure you are just detecting the requests you want to change, then extract the field values you need and finally generate the hash. Keep testing at each stage to make sure its doing what you need. And if you need specific help theres always the zaproxy-scripts group.

Delphi datasnap REST server PUT & POST management

Relation between REST CRUD operation and HTTP verbs are described at:
Using HTTP Methods for RESTful Services
Also, at Embarcadero REST overview it is covered with exmples:
REST overview
However, in implementation of mapping PUT and POST there is inconsistency:
Datasnap REST
Implemented behavior treat PUT as method for inserting new resource, and return code: 201(Create), but POST, as "update" prefix for related method suggest: return 200(OK).
If we put aside inconsistency in prefix of methods for PUT and POST and force regular return response code for insert new resource:
// User inserted in DB, obtain UserID
LUserID := LspUserInsert.FieldByName('UserID').AsString.Substring(1,36);
// Response on a new User inserted
with GetInvocationMetadata(True) do
begin
ResponseCode := 201;
ResponseContentType := 'application/json; charset=utf-8';
end;
//TODO: Set Location in the response header
GetDataSnapWebModule.Response.Location := LHTTPReq + '/' + LUserID;
end;
Is there better way to implement regular mapping of PUT and POST? Also, how to get additional information for Location in the header of the response for 201(Create):
http://[host]:[port]/[request_path]...
so, the insert method can create in the response header (for example):
Location=http://localhost:8080/datasnap/rest/TTestServerMethods/Users/D813258D-F3D3-42D3-8C5B-9D392442C8D0
Edited:
Sorry for incomplete information and using not so clear terms "better way" and "additional data".
I would like to solve the following issues in a more elegant way, if there is any:
Change method name. (Status: partially solved) Procedure for insert an user is named "updateUsers" due to datasnap REST prefix for POST which I want to use for create resource. The only was is to choose different name of method, but then REST request has to put method name in quotas ("insertUsers").
Generate expected response on datasnap REST request. (Status: SOLVED) Default behaviour of PUT on ok response is always 201(Create), and POST responds with 200(OK). Attached part of code solved 201(create) response.
So problem is partially solved, with additional code, consent to weird methods names or request that clients create requests with quoted resources. I believe that there is a "better way" to solve present datasnap REST implementation of PUT and POST, by means of override some methods of classes doing implementation of datasnap REST. I hope Embarcadero will fix this REST "misinterpretation" in following releases.
About Location. Usually, POST creates a resource and responds with 201(create) with accompanied location of created resource in the response header. In mentioned method I get created userID from a stored procedure, however I need data coming from HTTP request URI( host, port, path_to_resource), to create complete Location string. For above example, this "additional data" is: "http://localhost:8080/datasnap/rest/TTestServerMethods/Users/"

Twitter Oauth possible cause for 400 Bad Request response using a simple REST client

I've generated Access Tokens in the Settings/..../ Keys and Access Tokens page and now have a
Consumer Key
Consumer Secret Key
Owner ID (even though this was probably already generated)
Access Token
Access Token Secret
and am using a rest client to test being able to pull the latest 3 statuses using this api end point
https://api.twitter.com/1.1/statuses/user_timeline.json?user_id=userIdHere&count=3
as well as the following headers
Accept: /
Connection: close
User-Agent: OAuth gem v0.4.4
Content-Type: application/x-www-form-urlencoded
Content-Length: 76
Host: api.twitter.com
Authorization: OAuth
oauth_consumer_key=
oauth_signature=
oauth_signature_method=
oauth_timestamp=
oauth_token=
oauth_version=
obviously the 'userIdHere' in the end point address (above) is substituted with my username (i know i can also use my user_id, but that's beside the point) as well as the 'Authorization' values being substituted for real values. That's where my question lies...
What is the mapping for each of the 'oauth...' authorization parameters to their associated Twitter generated and provided Token or key(s) (which were mention near the top of the post)?
I keep getting a '400 Bad Request' response and feel that it is the authorization that is failing in that the permutations of key placements is incorrect. I do not know which value goes to which 'oauth...' value
finally, the structure of the 'Authorization' parameter header is as follows (as per instruction here from the Twitter EXAMPLE) as one line string value
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"
)
I am just trying to use a GET to get the last 3 statuses and have not been able to. Also, i plan to switch the values to Environmental Variables, but that doesn't matter yet..
UPDATE
using Postman now, and it's better at mapping, but now am getting
{
"errors": [
{
"code": 32,
"message": "Could not authenticate you."
}
]
}
For the Postman part make sure that you leave Timestamp and nonce empty and hit "update request" before you hit send. That will generate timestamp and nonce - otherwise you will get authorization failures every time. I just tried it with my twitter API credentials and it works.
For Oauth gem code, I find it strange that you have a Content-Type and a Content-Length header for a GET request. Looks like the 400 Bad request could be because you are attempting to do a POST to an endpoint that only supports GET. Indeed when I try to do a POST to that endpoint it tells me.
{
"errors": [
{
"code": 86,
"message": "This method requires a GET or HEAD."
}
]
}
So the 400 is actually good news - it means that authorization works, you are just calling the API in the wrong way.

The difference between XPOST and XPUT

I am learning Elasticsearch, I found that XPOST and XPUT are in general the same when 'update' or 'replace' documents. They all change the field values.
curl -XPUT 'localhost:9200/customer/external/1?pretty' -d '
{
"name": "Jane Doe"
}'
curl -XPOST 'localhost:9200/customer/external/1/_update?pretty' -d '
{
"doc": { "name": "Jane Doe" }
}'
So they all changed the name field to "Jane Doe". I am wondering whats the difference between XPOST and XPUT in the above context.
The two commands are not at all the same. The first one (with PUT) will update a full document, not only the field you're sending.
The second one (with POST) will do a partial update and only update the fields you're sending, and not touch the other ones already present in the document.
firstly, -X is a flag of curl.
please see -X in the man page. It is same as --request. You can specify which HTTP method to use (POST, GET, PUT, DELETE etc)
http://curl.haxx.se/docs/manpage.html
Regarding POST and PUT, they are HTTP methods or "verbs".
ElasticSearch provides us with a REST API. According to REST practices, POST is for create and PUT is for updating a record.
Please see:
http://www.restapitutorial.com/lessons/httpmethods.html
HTTP PUT:
PUT puts a file or resource at a specific URI, and exactly at that URI. If there's already a file or resource at that URI, PUT replaces that file or resource. If there is no file or resource there, PUT creates one. PUT is idempotent, but paradoxically PUT responses are not cacheable.
HTTP 1.1 RFC location for PUT
HTTP POST:
POST sends data to a specific URI and expects the resource at that URI to handle the request. The web server at this point can determine what to do with the data in the context of the specified resource. The POST method is not idempotent, however POST responses are cacheable so long as the server sets the appropriate Cache-Control and Expires headers.
The official HTTP RFC specifies POST to be:
Annotation of existing resources;
Posting a message to a bulletin board, newsgroup, mailing list, or similar group of articles;
Providing a block of data, such as the result of submitting a form, to a data-handling process;
Extending a database through an append operation.
HTTP 1.1 RFC location for POST
Difference between POST and PUT:
The RFC itself explains the core difference:
The fundamental difference between the POST and PUT requests is reflected in the different meaning of the Request-URI. The URI in a POST request identifies the resource that will handle the enclosed entity. That resource might be a data-accepting process, a gateway to some other protocol, or a separate entity that accepts annotations. In contrast, the URI in a PUT request identifies the entity enclosed with the request -- the user agent knows what URI is intended and the server MUST NOT attempt to apply the request to some other resource. If the server desires that the request be applied to a different URI, it MUST send a 301 (Moved Permanently) response; the user agent MAY then make its own decision regarding whether or not to redirect the request.
Using the right method, unrelated aside:
One benefit of REST ROA vs SOAP is that when using HTTP REST ROA, it encourages the proper usage of the HTTP verbs/methods. So for example you would only use PUT when you want to create a resource at that exact location. And you would never use GET to create or modify a resource.
upvote if it helps you :)
PUT method is idempotent so if you hit payload with put method, it will create first time only and if you hit the same request again and again, it won't create new records, it will simply update the previously created.
On the other hand if you hit the payload with POST method no of times you will create a no of entries of same payload.

Apigility code-connected service - for POST method

I am a newbie to the apigility code-connected service & was able to create a RESTful service with fetch and fetchall class method on the mapper file.
Can someone point me a good sample for insert (POST) data via REST service ?
Thank you,
Kevin
POST is going to be used for creating a new resource typically. This means that in your request you're going to want the following headers:
Accept: application/json
Content-Type: application/json
The first tells Apigility what sort of a response it is expecting. The second says that the data you'll be providing to the API will be in json format.
Apigility uses json or json+hal by default for a return and expects json for the incoming data.
When you're creating a new resource, typically you'll be persisting it in a database and as such the id of the resource will be generated by your code or database. The rest of the resource will be provided by the caller to the API. Example:
POST /api/user
{
"username": "kevin voyce",
"firstname": "kevin",
"lastname":" "voyce"
}
If you do this, you should see a response of something like
405 - Method Not Allowed
The body of the error should indicate that the method has not been defined. The error message is coming from the create method in the resource. Inside this method, you'll see an argument called $data which at this point will consist of a PHP stdClass with fields matching the stuff you passed in via the JSON body.
This is where the fields part of configuring your API in Apigility comes in. If you set up the names of the fields and put validators on the fields, Apigility will make sure that the fields that are passed in conform to and are valid according to these validators before the call is made into your API. The same applies to not just POST, but PATCH and PUT as well. This means that within your methods you don't have to worry that the input hasn't been validated (as long as you correctly configured your validators).