API Authentication

Lift22 is een project dat veel aspecten heeft. Eentje daarvan is de API. De API gebruiken we voor de communicatie met de back-end, met de databases dus. Omdat dit belangrijk is, was één van de prioriteiten om er voor te zorgen dat de API veilig is. Naast het feit dat de data die we aanleveren correct moet zijn, moet de data niet zomaar bij iedereen terecht komen. Publieke toegang is nu eenmaal niet handig als je met privégegevens omgaat.

Daarom hebben we gekozen om de gebruikers van de API te laten authenticeren. Dit wilden we dus implementeren. Makkelijker gezegd dan gedaan, er zijn talloze authenticatieplatformen. De meest gebruikte zijn:

  • OAuth: gebruikt door onder andere Facebook, Foursquare, Github, Twitter en nog veel meer
  • HTTP Basic authentication: Gebruik maken van het HTTP-protocol.
  • Public key cryptography.

Omdat de implementatie en veiligheid voor onze API vrij belangrijk is, hebben we gekozen voor de public key cryptography. OAuth zou ook een optie geweest zijn, maar is eigenlijk té uitgebreid voor onze RESTful API.

Public key cryptography is eigenlijk een vrij simpel concept. Ontwikkelaars die onze API willen gebruiken, registreren zich en maken een applicatie aan. Bij deze applicatie hoort een public en private key. Bij het maken van een request moet de de public key leesbaar meegestuurd worden, vandaar de ‘public’. Echter, de private key ‘signed’ de request. ‘Signen’ is de request encrypten met de private key. Deze ‘signed request’ wordt dan ook meegestuurd naar de API-server. De server bekijkt de public key, haalt de private key op uit de database en ‘signed’ de request dan aan de serverkant. De server vergelijkt dan de verstuurde ‘signed’ request met zijn eigen gegenereerde request. Als deze hetzelfde zijn, is de request verified.

Simpel voorgesteld:

  1. Client bouwt request: https://api.lift22.be/routes/Hasselt/Gent/20/json
  2. Client voegt public key toe: https://api.lift22.be/routes/Hasselt/Gent/20/json?key=abc
  3. Client signed request met hmac sha256: https://api.lift22.be/routes/Hasselt/Gent/20/json?key=abc&sig=daslkj324iuo4alsd4230984
  4. Client stuurt data naar API-server
  5. Server ontvangt data
  6. Server bekijkt public key (key=abc) en haalt private key op
  7. Server signed de request (routes/Hasselt/Gent/20/json): daslkj324iuo4alsd4230984
  8. Server vergelijkt eigen signed request met geleverde signed request
  9. Server stuurt data terug

De data van de server ziet er dan zo uit:

{
"auth": {
 "authenticated": true,
 "authenticationMessage": "Signatures valid"
 },
 "data": {
 "results": [
 {
 "user": {
 "userID": "33",
 "passengers": 2,
 "date": "8-5-2013",
 "time": "14:53"
 },
 "departure": {
 "country": "BE",
 "region": "Flemish Brabant",
 "city": "Leuven",
 "zip": "3000",
 "address": "Galgebergstraat 38-56",
 "coordinates": {
 "lon": 50.888070789806,
 "lat": 4.6784909335938
 },
 "distance": null
 },
 "destination": {
 "country": "BE",
 "region": "East Flanders",
 "city": "Gentbrugge",
 "zip": "9050",
 "address": "Oefenpleinstraat 1",
 "coordinates": {
 "lon": 51.031658550844,
 "lat": 3.7556393710938
 },
 "distance": null
 }
 },
 {
 "user": {
 "userID": "35",
 "passengers": 2,
 "date": "8-5-2013",
 "time": "14:53"
 },
 "departure": {
 "country": "BE",
 "region": "Flemish Brabant",
 "city": "Diest",
 "zip": "3293",
 "address": "Zeven Zillenerf 23",
 "coordinates": {
 "lon": 50.976351971962,
 "lat": 5.0190671054688
 },
 "distance": null
 },
 "destination": {
 "country": "BE",
 "region": "East Flanders",
 "city": "Berlare",
 "zip": "9290",
 "address": "Nieuwdonk",
 "coordinates": {
 "lon": 51.031658550844,
 "lat": 3.9781125156251
 },
 "distance": null
 }
 },
 {
 "user": {
 "userID": "3",
 "passengers": 2,
 "date": "8-5-2013",
 "time": "14:53"
 },
 "departure": {
 "country": "BE",
 "region": "Walloon Brabant",
 "city": "Nivelles",
 "zip": "1400",
 "address": "Chemin de Baudemont",
 "coordinates": {
 "lon": 50.623963560944,
 "lat": 4.2939694492188
 },
 "distance": null
 },
 "destination": {
 "country": "BE",
 "region": "Antwerp",
 "city": "Westerlo",
 "zip": "2260",
 "address": "Moestoemaat 48",
 "coordinates": {
 "lon": 51.126562725252,
 "lat": 4.9339230625001
 },
 "distance": null
 }
 },
 {
 "user": {
 "userID": "9",
 "passengers": 2,
 "date": "8-5-2013",
 "time": "14:53"
 },
 "departure": {
 "country": "BE",
 "region": "Flemish Brabant",
 "city": "Oud-Heverlee",
 "zip": "3053",
 "address": "Graumereweg 2",
 "coordinates": {
 "lon": 50.839531419753,
 "lat": 4.7196896640626
 },
 "distance": null
 },
 "destination": {
 "country": "BE",
 "region": "Antwerp",
 "city": "Deurne",
 "zip": "2100",
 "address": "Parkweg",
 "coordinates": {
 "lon": 51.217831720141,
 "lat": 4.4615109531251
 },
 "distance": null
 }
 },
 {
 "user": {
 "userID": "1",
 "passengers": 2,
 "date": "8-5-2013",
 "time": "14:53"
 },
 "departure": {
 "country": "BE",
 "region": "Flemish Brabant",
 "city": "Leuven",
 "zip": "3000",
 "address": "Vanden Tymplestraat 20",
 "coordinates": {
 "lon": 50.882872560044,
 "lat": 4.7114499179688
 },
 "distance": null
 },
 "destination": {
 "country": "BE",
 "region": "East Flanders",
 "city": "Kruibeke",
 "zip": "9150",
 "address": "Donkerstraat 7",
 "coordinates": {
 "lon": 51.14724322443,
 "lat": 4.2884762851563
 },
 "distance": null
 }
 },
 {
 "user": {
 "userID": "50",
 "passengers": 2,
 "date": "8-5-2013",
 "time": "14:53"
 },
 "departure": {
 "country": "BE",
 "region": "Flemish Brabant",
 "city": "Leuven",
 "zip": "3000",
 "address": "Professor Van Overstraetenplein",
 "coordinates": {
 "lon": 50.877673750248,
 "lat": 4.7169430820313
 },
 "distance": null
 },
 "destination": {
 "country": "BE",
 "region": "Hainaut",
 "city": "Mons",
 "zip": "7000",
 "address": "Avenue Joseph Wauters 126-128",
 "coordinates": {
 "lon": 50.447646492861,
 "lat": 3.9341672031251
 },
 "distance": null
 }
 },
 {
 "user": {
 "userID": "93",
 "passengers": 2,
 "date": "8-5-2013",
 "time": "14:53"
 },
 "departure": {
 "country": "BE",
 "region": "Flemish Brabant",
 "city": "Leuven",
 "zip": "3000",
 "address": "Dijledreef 2",
 "coordinates": {
 "lon": 50.891535954084,
 "lat": 4.7087033359376
 },
 "distance": null
 },
 "destination": {
 "country": "BE",
 "region": "Hainaut",
 "city": "Mons",
 "zip": "7020",
 "address": "Rue Notre Dame du Petit Nimy",
 "coordinates": {
 "lon": 50.472125833229,
 "lat": 3.9671261875001
 },
 "distance": null
 }
 },
 {
 "user": {
 "userID": "50",
 "passengers": 2,
 "date": "8-5-2013",
 "time": "14:53"
 },
 "departure": {
 "country": "BE",
 "region": "Limburg",
 "city": "Hasselt",
 "zip": "3500",
 "address": "Kroonwinningstraat 2-14",
 "coordinates": {
 "lon": 50.920979443385,
 "lat": 5.3486569492188
 },
 "distance": null
 },
 "destination": {
 "country": "BE",
 "region": "East Flanders",
 "city": "Gentbrugge",
 "zip": "9050",
 "address": "E17",
 "coordinates": {
 "lon": 51.042021194522,
 "lat": 3.7831051914063
 },
 "distance": null
 }
 },
 {
 "user": {
 "userID": "33",
 "passengers": 2,
 "date": "8-5-2013",
 "time": "14:53"
 },
 "departure": {
 "country": "BE",
 "region": "Limburg",
 "city": "Genk",
 "zip": "3600",
 "address": "Albrecht Rodenbachlaan 51-53",
 "coordinates": {
 "lon": 50.964244867622,
 "lat": 5.4777463046876
 },
 "distance": null
 },
 "destination": {
 "country": "BE",
 "region": "Limburg",
 "city": "Hasselt",
 "zip": "3500",
 "address": "Sint-Truidersteenweg",
 "coordinates": {
 "lon": 50.912321526677,
 "lat": 5.3211911289063
 },
 "distance": null
 }
 },
 {
 "user": {
 "userID": "1",
 "passengers": 2,
 "date": "8-5-2013",
 "time": "14:53"
 },
 "departure": {
 "country": "BE",
 "region": "Limburg",
 "city": "Hasselt",
 "zip": "3500",
 "address": "Woutersstraat 1",
 "coordinates": {
 "lon": 50.927875996205,
 "lat": 5.3314119
 },
 "distance": null
 },
 "destination": {
 "country": "BE",
 "region": "Antwerp",
 "city": "Geel",
 "zip": "2440",
 "address": "Molseweg 90",
 "coordinates": {
 "lon": 51.164387599943,
 "lat": 5.0306611675782
 },
 "distance": null
 }
 }
 ],
 "stats": {
 "resultCount": 10
 }
 }
}

Een blog

Yep, een blog. We posten vooral over onze ontwikkelingen van Lift22, maar we houden jullie ook op deze manier op de hoogte van enige wijzigingen aan de API, komende veranderingen aan de website, en meer van dat.