Authorization Flows¶
The Open Id Connect and OAuth 2.0 specifications define various ways clients can authenticate and/or get permission from users to act on their behalf. These are called authorization grant flows. Depending on the type of application, the environment and the intended use case, some flows are better suited than others. Some flows are intended to have user interactions, while others are used for machine to machine communication.
The output of each flow is an access token, which can be used to make calls to TrackMan APIs and access resources on behalf of the users. Tokens have a limited lifetime and expire after a specified amount of time. Depending on the authorization flow used, there are different ways to refresh that access token with limited or no user interaction.
Scopes¶
When client applications request a token, they specify one ore more resources that they want to access with that token. Those resources are grouped into scopes
. Scopes are just names for permission to access a set of resources. The Open Id Connect specification defines a set of standard scopes, in order for client applications to be able to get a user's identification, profile information, etc.
Note
The generated access token can only access the resources of scopes it has been granted and nothing more. If access to additional resources is required, the appropriate scope must be specified before requesting an access token.
Driving Range Scopes¶
TrackMan Driving Range requires client applications to have been granted the following scopes in order to call Driving Range APIs:
Scope | Description |
---|---|
openid | Get the TrackMan unique user identifier in the sub (subject) claim |
profile | Get basic user profile information (first name, last name, etc.) |
email (optional) | Get the user's primary email address |
roles | Get the user's Driving Range specific roles |
offline_access (optional) | Get an additional refresh token along with the access token |
Additionally to the aformentioned standard scopes, TrackMan Driving Range defines the following custom scope that client applications must be granted in order to access player sessions:
https://auth.trackman.com/dr/play: Allows the client application to get a list of the Driving Range's bays and targets, start/end play sessions and subscribe to measurements during a play session.
Note
Openid scopes (profile, email, etc.) are only valid in a request if the client app asks for an id_token
along with the access token. Otherwise the request will be invalid. If you are only interested in an access token, include only the TrackMan spefic scopes in the authorization request.
Bellow you can find a list of authorization flows and their intended use:
Authorization Code Flow¶
The auhorization code flow is the most secure of all flows and it requires interaction with a user. The steps in this flow are as following:
-
The client application redirects the user to the authentication server's authorization endpoint, requesting access to one or more resources (scopes).
-
The user logins or creates a new account on the authentication server.
-
The user is presented with a consent screen to allow the client application to access the requested resources on his or her behalf.
-
The authentication server redirects the user to the redirect uri that the specified client application has registered with, passing along either an error or an authorization code.
-
The client application makes a second request to the authentication server's token endpoint through a secure backchannel, passing its client id and client secret and exchanges the authorization code for an access token and optionally a refresh token.
-
The client application can now access TrackMan APIs on behalf of the user using the provided access token.
To authenticate the user, redirect to the authorization url like in the following example:
GET /connect/authorize? response_type=code &client_id={YOUR-CLIENT-ID} &redirect_uri={YOUR-REDIRECT-URI} &scope=openid profile email roles offline_access https://auth.trackman.com/dr/play Host: https://login.trackmangolf.com
The authentication sever will then pass the authorization code and granted scopes to your application's registered redirect uri:
GET {YOUR-REDIRECT-URI}? code=20f3c53b1b7381644ddd0eb71843cba6bbc4b2da5b889d65fa906 &scope=openid profile email roles offline_access https://auth.trackman.com/dr/play
Note
Your application could be granted fewer scopes than originally requested (i.e. if the user doesn't consent to everything). It's up to each individual application how to handle this scenario.
Next, exchange the authorization code for an access_token
:
POST /connect/token? grant_type=authorization_code &code=20f3c53b1b7381644ddd0eb71843cba6bbc4b2da5b889d65fa906 &client_id={YOUR-CLIENT-ID} &client_secret={YOUR-CLIENT-SECRET} &redirect_uri={YOUR-REDIRECT-URI} Host: https://login.trackmangolf.com
Best Practice
For better security, it is advisable to pass the client_id and client_secret in the Authorization header instead of the url, using the Basic authentication scheme.
A successful response will look like the following example:
Content-Type: application/json; charset=utf-8 { "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE0NzkyOTk2N", "expires_in": 3600, "token_type": "Bearer", "refresh_token": "d39f7727557f60d06138bba50c1e24e13889088c92e57f03f84" }
Warning
This authorization code flow requires a secure backchannel (i.e. a Web Server) to redirect to from the authentication server and to transfer the client credentials when connecting to the token endpoint. The client credentials should never be exposed through an insecure agent like a browser or a mobile app that can be reverse engineered.
Implicit Flow¶
This flow should be used to obtain a token when there isn't a secure backchannel available. It's being used primarily by SPA (Single Page Application) clients and native/mobile clients where they can't securely transmit a client secret to the authentication server. It requires user interaction.
The steps in this flow are as following:
-
The client application redirects the user to the authentication server's authorization endpoint, requesting access to one or more resources (scopes).
-
The user logins or creates a new account on the authentication server.
-
The user is presented with a consent screen to allow the client application to access the requested resources on his or her behalf.
-
The authentication server redirects the user to client application's registered redirect uri, passing along either an error or an access token in the uri's fragment component.
Example request:
GET /connect/authorize? response_type=token &client_id={YOUR-CLIENT-ID} &redirect_uri={YOUR-REDIRECT-URI} &scope=https://auth.trackman.com/dr/play Host: https://login.trackmangolf.com
Successful response:
GET {YOUR-REDIRECT-URI}# access_token=xxx &token_type=Bearer &expires_in=3600 &scope=https://auth.trackman.com/dr/play
A javascript client can read the access token and the rest of the information from the fragment component.
Client Credentials Flow¶
This flow is used for machine to machine communication and is N/A for client applications currently in Driving Range.
Resource Owner Password Flow¶
The OAuth 2.0 resource owner password grant allows a client to send username and password to the token service and get an access token back that represents that user.
This flow consists of only one request to the authentication server, as shown in the example below:
Content-Type: application/x-www-form-urlencoded POST /connect/token grant_type=password &username={USERNAME} &password={PASSWORD} &client_id={YOUR-CLIENT-ID} &scope=https://auth.trackman.com/dr/play Host: https://login.trackmangolf.com
Successful response:
Content-Type: application/json; charset=utf-8 { "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE0NzkyOTk2N", "expires_in": 3600, "token_type": "Bearer" }
Refreshing Access Tokens¶
For certain flows, you can request a refresh_token
along with the access_token
in order to periodically update the access_token
before or after it expires, without requiring any user interaction.
To request a refresh_token
, just add the offline_access
scope to the initial auhorization request.
You should get a response that looks like the following:
{ "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE0NzkyOTk2N", "expires_in": 3600, "token_type": "Bearer", "refresh_token": "2b4b2b92fc22ad64a02a2c0cf69a8e7baab27ea42115dcaa1e15a634137b8fb9" }
You can now use the refresh_token
to acquire a new access_token
from the token endpoint:
Content-Type: application/x-www-form-urlencoded POST /connect/token grant_type=refresh_token &refresh_token={REFRESH-TOKEN} &client_id={YOUR-CLIENT-ID} &client_secret={OPTIONAL-CLIENT-SECRET} Host: https://login.trackmangolf.com
You should get a new access_token
and a new refresh_token
. Previous refresh tokens cannot be reused.
Social Media Login¶
Logging in with one of the supported social media providers closely resembles the authorization code flow. The difference is that the actual login will take place in the social media provider's website, but the access and refresh tokens are going to be generated by the TrackMan authentication server.
The flow is as follows:
-
The client application redirects the user to the TrackMan authentication server, providing information about the social media provider it wants to login with in the form of a
acr_values
querystring parameter. Valid values at the time of this writing includeidp:Facebook
andidp:Google
. -
The TrackMan authentication server redirects the user to the specified social media provider.
-
The user logs in on the social media provider's website.
-
The user is redirected back to the TrackMan authentication server. If the user does not already have a TrackMan account, a new one is going to be created automatically using the information from the social media provider.
-
The user is redirected back to the client application and the client application receives an
authorization code
. -
The client application exchanges the
authorization code
for anaccess token
and arefresh token
.
GET /connect/authorize? response_type=code &client_id={YOUR-CLIENT-ID} &redirect_uri={YOUR-REDIRECT-URI} &scope=offline_access https://auth.trackman.com/dr/play &acr_values=idp:Facebook Host: https://login.trackmangolf.com
After redirected back to the client application, an access code will be provided as part of the querystring parameters, which can be exchanged for an access token
and refresh token
:
POST /connect/token? grant_type=authorization_code &code=20f3c53b1b7381644ddd0eb71843cba6bbc4b2da5b889d65fa906 &client_id={YOUR-CLIENT-ID} &redirect_uri={YOUR-REDIRECT-URI} Host: https://login.trackmangolf.com
A successful response will look like the following example:
Content-Type: application/json; charset=utf-8 { "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE0NzkyOTk2N", "expires_in": 3600, "token_type": "Bearer", "refresh_token": "d39f7727557f60d06138bba50c1e24e13889088c92e57f03f84" }
Facebook Native Login¶
This flow is intended for native mobile applications that want to provide the best possible experience for their users, by letting them login using the installed Facebook App on their phone.
After acquiring an access token from Facebook, clients can exchange that token for a TrackMan Range access token which can be used to authorize calls in all TrackMan Range APIs.
The steps of this flow are as follows:
-
The client app uses Facebook Native Login to acquire an access token.
-
The client app initiates a token request to the TrackMan authentication server, specifying
fb_access_token
as thegrant_type
and providing (among other things) the Facebook access token with the request. -
The TrackMan authentication server verifies the access token with Facebook, creates a new TrackMan account if necessary and returns a standard TrackMan Range access token.
POST /connect/token? grant_type=fb_access_token &token={FACEBOOK-ACCESS-TOKEN} &client_id={YOUR-CLIENT-ID} &scope=offline_access https://auth.trackman.com/dr/play Host: https://login.trackmangolf.com
A successful response will look like the following example:
Content-Type: application/json; charset=utf-8 { "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE0NzkyOTk2N", "expires_in": 3600, "token_type": "Bearer", "refresh_token": "d39f7727557f60d06138bba50c1e24e13889088c92e57f03f84" }