2. Exposing “Hello world!”¶
The service developed the previous chapter can now be exposed to the rest of the world using our frontend webserver.
To make this happen, we have to construct a mapping to bind an endpoint (https://<host>/api/<module>/<service>) to the service, next item on the list is testing the service. To grasp the concept we will keep it simple here, and use the root user to access the service. This way we don’t have to worry about access (yet).
Note
The actions on this page are executed on the frontend server, except the Python script, which should be created and run locally, like the examples in the previous chapter.
Create a controller¶
First create the directory needed to publish our service:
mkdir -p /usr/local/opnsense/mvc/app/controllers/ValueA/Samples/Api
Then create two files in the directory created above.
1<?php
2
3namespace ValueA\Samples\Api;
4
5use ValueA\Base\ApiQueueControllerBase;
6
7class HelloController extends ApiQueueControllerBase
8{
9}
The namespace tag indicates the location of the file seen from the controller directory, the class name should be identical to the filename.
Note
The php class can be extended, but usually the stub derived from ApiQueueControllerBase is enough to publish services.
1<route>
2 <world>
3 <bind>valuea.samples.helloworld</bind>
4 <type>GET</type>
5 </world>
6</route>
The routing file is actually quite simple, line 1 tells the system this is a routing, then the next line (2) the location seen from the controller (so this is /api/samples/hello/world), followed by (3) the service it wants to call. Finally we tell the controller for what type of request this service is meant (GET in this case).
Note
Don’t use GET type request when changing data, the default safe guards to prevent Cross-Site Request Forgery won’t work.
Test using a browser¶
Because the above routing expects a get type request, we can easily test by logging in to OPNsense and browsing to the
api endpoint https://<host>/api/samples/hello/world.
Note
Don’t forget to login to OPNsense first, otherwise an empty page is returned (http status code 401)
Retrieving your first API key (and secret)¶
When developing frontend applications, with a user interface installed on the OPNsense machine itself, we’re ready to start creating webpages (which can use our service). If we’re providing our service to another party, we still need to provide access to it.
For this purpose OPNsense delivers api keys, which can be created on a per user basis. For our test we are going to create an api key for the root user, which we then will use to execute the same request using a http library.
First thing to do is to acquire a key, go to the OPNsense in your web browser, then System -> Access -> Users and edit the root user, next click the plus sign near the “API keys” section to retrieve a key+secret combination.
Note
The key+secret will be downloaded to your local machine, open it and read the contents.
Note
We haven’t explained the ACL concept yet, so at this point you can only export keys for the root user to gain access to “helloworld”
The downloaded file contains something like this:
key=CQoy/h5PREgAiE4hRgTrajolHqjqtxNaLxohg/ylWnt5+1NKMeSxvoj3O2jeNpRjnmMqxUVgXlbJurOc
secret=iEeZfNVkl2joOaZ08oO6UoIgPOejKoxtK4wdrhVHZc3S2AfjqnNDO4yG/TCPB4CN676yaaTItk8mx925
Using python to execute “Hello world!”¶
There is a very convenient library named “requests” available for python, which we will use to execute a call to our webserver.
1#!/usr/bin/env python
2import requests
3
4# define endpoint and credentials
5api_key = 'CQoy/h5PREgAiE4hRgTrajolHqjqtxNaLxohg/ylWnt5+1NKMeSxvoj3O2jeNpRjnmMqxUVgXlbJurOc'
6api_secret = 'iEeZfNVkl2joOaZ08oO6UoIgPOejKoxtK4wdrhVHZc3S2AfjqnNDO4yG/TCPB4CN676yaaTItk8mx925'
7url = 'https://192.168.56.102/api/samples/hello/world'
8
9# request data
10r = requests.get(url,
11 verify=False,
12 auth=(api_key, api_secret))
13
14if r.status_code == 200:
15 print ('Received %s' % r.text)
16else:
17 print ('Connection / Authentication issue, received %s' % r.text)
The API key and secret will use basic authentication headers, requests offers easy support to add them
to your request (12), the service called is the same is our previous browser test.
Tip
Our example uses verify=false, which will ignore the SSL trust relation. In production environments you don’t want to
do this (either make sure there’s a valid certificate installed or use the expected public key in your request).