Skip to content

Token handling

In this section we discuss the token handling of the openOBD service. This documentation is only relevant when you do not want to use the provided python libraries and/or want to implement openOBD in a different client language.

In our examples we use a Python openOBD implementation (see openobd project on PyPi). This library will take care of the procedure to set up a openOBD session. Since the openOBD project uses gRPC as its base technology, it is possible to use other client language implementations as well. All requests that are made to the openOBD service do need some form of authentication. For this reason all requests, except the getSessionControllerToken() call, need a token to be sent along with the request.

Session controller authentication

The first step in setting up an openOBD session is authentication. Who wants to create an openOBD session or wants to list the existing sessions? The first call that needs to be made is:

It takes the Authenticate message as input. The required fields of this message are: client_id, client_secret and cluster_id. How the values for these fields can be obtained is explained in the API credentials section of the quick start.

Session controller calls

In the openOBD protocol we make use of so-called bearer token authentication. Since openOBD uses gRPC this means that the RPC calls are transported using the HTTP2 protocol. Every function call translates into a HTTP2 call. For instance, when you want to make a call to the function startSessionOnTicket() this will translate to a HTTP2 call to the following endpoint:

    https://grpc.openobd.com/openOBD.v1.sessionController/startSessionOnTicket

How do we determine which partner is requesting to start an openOBD session? We use a bearer token that is sent along with every request that is made to the openOBD service. All calls to the SessionController (openOBD.v1.sessionController/*), responsible for session management, need to have the session controller token present in the header of the call.

For example, the call to startSessionOnTicket will look like this:

call  openOBD.v1.sessionController/startSessionOnTicket
header authorization: [value of SessionControllerToken]
inputTicketId
outputSessionInfo

Session authentication

The call above will result in freshly created openOBD session. The SessionInfo object refers to this session and contains an authentication_token. This token can be used to make only one call to the freshly created session:

call  openOBD.v1.session/authenticate
header authorization: [value of authentication_token in SessionInfo]
inputEmptyMessage
outputSessionToken

Once this call has been made, all other calls related to the openOBD session need to have a session token as bearer token. For instance, the call to open an ISOTP stream:

https://grpc.openobd.com/openOBD.v1.can/openIsotpStream

How do we determine to which openOBD session this call refers? And is the client actually allowed to make this call? This is determined by the bearer token that is sent along with the HTTP2 request.

The call to openIsotpStream will look like this:

call  openOBD.v1.can/openIsotpStream
header authorization: [value of SessionToken]
input stream IsotpMessage
output stream IsotpMessage

Since this needs to be done for every request we devised a method for it in our Python openOBD client library. The function adds metadata to every call that is being made. It is smart to use a method like this in your own implementation, since every openOBD call needs this. The method looks like this:

1
2
3
4
5
def _metadata(self):
    metadata = []
    metadata.append(("authorization", "Bearer {}".format(self.session_token)))
    metadata = tuple(metadata)
    return metadata

The call to the gRPC function openIsotpStream() for instance, as shown in the code example below, makes a call to the function self._metadata() in order to add the bearer token.

@raises_openobd_exceptions
def open_isotp_stream(self,
        isotp_messages: Iterator[grpcIsotp.IsotpMessage]) \
            -> Iterator[grpcIsotp.IsotpMessage]:
    """
    Opens a bidirectional stream for ISO-TP communication 
    with the channel specified in the given IsotpMessage.

    :param isotp_messages: 
        each IsotpMessage that should be sent to the
        specified channel.
    :return: 
        IsotpMessages sent by the specified channel.
    """
    return self.can.openIsotpStream(isotp_messages, metadata=self._metadata())

Depending on the implementation language the code will be slightly different, but the key concept is to add the authorization header to every call that is being made.

Authorization: Bearer MTAuMTMwLjYyLjI5OzMw ... CODA2NURFMUNGRjMyMzYzNjQyNkFBNzIz

Session keep-alive

A running openOBD session needs to refresh its session token (value of the SessionToken) every 2 minutes. This refreshing is controlled by the server process. It will send a new session token every 2 minutes over a stream. For a running openOBD session this refreshing is crucial and an incoming stream should always be open. Any updates on the SessionToken should be processed and consecutive calls should use the latest received openOBD session token.

To open the incoming session token stream on a session the openSessionTokenStream call can be used:

call  openOBD.v1.session/openSessionTokenStream
header authorization: [value of SessionToken]
inputEmptyMessage
output stream SessionToken

Summary

In openOBD two token types are used.

  • The SessionController token
  • The Session token

The first token (SessionController token) is used for calls to the SessionController. These calls all have the following prefix: https://grpc.openobd.com/openOBD.v1.sessionController

The SessionController creates a different token for every session that is created.

Before performing services on an active session, it is required to ensure that the session remains authenticated with the client implementation. The service openSessionTokenStream() allows for this. This service returns a SessionToken which is required to be updated in the header as the bearer token of the gRPC calls being made during the session. It proves the client is authenticated to the session and can carry out the services required to perform the desired diagnostic service.