1. Authentication
Using the library
HatForIOS provides features that enable your app to authenticate with the PDA, read/write to the PDA, fetch and setup Data Plugs and Applications, fetch Data debits and use advanced features like Combinators and Bundles.
Authentication with a PDA
The PDA is an API-only service, meaning it does not enforce a specific Application or User Interface to expose the data to the user. Instead, authentication happens using the PDA APIs and the Javascript Web Token (JWT). Each PDA runs as a separate server and has a publicly-reachable address (such as https://postman.hubat.net). All calls in this documentation are therefore executed against an individual PDA.
Overview
The steps to logging in with a PDA are:
You send the user to
/hatloginendpoint on their PDA, such ashttps://postman.hubat.netThe PDA user enters their login details through the login screen and verifies the service they are logging into
User is redirected back to the address you have provided with the authentication token in a query parameter. You validate the token against the PDA’s public key to confirm that the user owns the specific PDA and log them in.
Step 1 - Redirect user to PDA Login
To log the user in with their PDA, you need to ask for their PDA address. Depending on the status of your app within the HAT ecosystem, you may also have a specific application name, an allowed success redirect url and an allowed fallback redirect url to which the user is sent to complete authentication.
If you do not have these details, you can put any application name, success redirect url and fallback redirect url. However, the authentication token you receive will not grant you any permissions to do any operations on the PDA; it can only verify that the token really came from the DA (further details about step 1 here).
For an iOS application this means asking the user to type the PDA Address. Here's a very simple example:

In the above image, the user is asked to fill the PDA address, postman and select a domain, .hubat.net. There can be other domains as well, e.g.hat.direct. We think that splitting the address and the domain makes for a better UX, but this is not a requirement for your app. You could have one UITextField where the user will have to type the full address, postman.hubat.net
Once you've asked the user to fill in the PDA address, e.g. postman.hubat.net, you have to send them to the "https://\(hatAddress)/#/hatlogin?name=\(applicationName)&redirect=\(redirectURL)&fallback=\(fallbackRedirectURL)" endpoint of the PDA, where:
hatAddressis the PDA's (fully qualified domain) address, e.g.postman.hubat.netapplicationNameis your application's name on the PDA. This is defined once you complete the form to create a new application. e.gtestingredirectURLis the URL to which the user should be sent upon completing authentication. Optional. For aniOSapplication that would probably be:applicationName://successand this has to be added in theinfo.plistfile of the project in Xcode as a URL scheme.fallbackRedirectURLis the URL to which the user should be sent in case the authentication has failed. Optional. For aniOSapplication that would probably be:applicationName://failedand this has to be added in theinfo.plistfile of the project in Xcode as a URL scheme.
In an iOS application, in order to redirect the user to an existing PDA address and proceed to the next step, we have to use Safari to open the URL. This is achieved by using the various ways iOS offers, e.g. SFSafariViewController.
To achieve this with SFSafariViewController you have to initialise an instance of SFSafariViewController with the login address described above: "https://\(hatAddress)/#/hatlogin?name=\(applicationName)&redirect=\(redirectURL)&fallback=\(fallbackRedirectURL)", and then via a UIViewController present the instance of SFSafariViewController. e.g.:
import SafariServices
let safariViewController: SFSafariViewController = SFSafariViewController(url: authURL)
viewController.present(safariViewController, animated: animated, completion: completion)That will launch Safari within the app and load the url specified.
Step 2 - Logging in the User
In the next step, users will be asked to fill in the password for the particular PDA Address:

This screen cannot be modified in any way. Users have to insert the password for the specified PDA and tap LOGIN.
Note that the complete address is served via SSL, contains the PDA's name as well as the application parameters:
application name,redirect urlandfallback redirect url.
By tapping LOGIN the authentication process will begin. PDA will use one of the two redirect url that were included in the request:success redirect if everything went ok or fallbackRedirectURL if an error occurred. The application has to know how to respond in both scenarios.
To achieve that, we have to add the success redirect and fallbackRedirectURL to the Info.plist file in the project.
To add them to the Info.plist file you have to add the Key URL Types as an Array.

Then add one item in that array of type Dictionary. The first item of the dictionary will be the URL Identifier which is the reverse url domain of your project. eg. com.hubofallthings.test. The second item of the dictionary will be URL Schemes which is Array again. In this array add one String value and name it as you want; the best practice is to use the name of your app. This will be your app's url scheme. That means every time iOS intercepts a URL starting with this value, like test://host will hand the process to your app which will be responsible for either launching it or not.

To decide if the app has to launch or not, you have to add to your AppDelegate file the following function:
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> BoolThis is the function that iOS triggers when it receives a URL which matches the URL Schemes that you defined in your Info.plist file; find more info about this here. All that you have to do in this function is to check the URL and if you recognise it, return true or else return false.
Step 3 - Verifying the login
Success callback
When the user logs in, they are redirected to the URL provided, with token query parameter appended and containing a RS256-signed JWT token, e.g.:
dataswift-sandbox://dataswift-sandboxhost?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhcHBsaWNhdGlvblZlcnNpb24iOiIxLjIuNyIsInN1YiI6IjEtT0tRdm1TdGdCZ0lKdm9mNUN6NktsMnhaYjhXMUszQmZFR28xa2dZVERCQmdLeUR0ZDBqOXp6VWRaUmlRdFloaFY2VjQ5a1g1WUlmTzE0K3lEcm1GUlwvN1RkUW1iWXNMS3BDST0iLCJhcHBsaWNhdGlvbiI6ImhhdGFwcHN0YWdpbmciLCJpc3MiOiJ0ZXN0aW5nLmh1YmF0Lm5ldCIsImV4cCI6MTU0NDA4Nzc3MiwiaWF0IjoxNTQxNDk1NzcyLCJqdGkiOiI5ZjdlN2MyOTYwMjZkNmM4ODBmN2M2ZTk0MzIzOTQ3Yzg2YmI2OGEwZTIxN2YxZmZhYWE2ZTY3NGYwYWE1ODRmOWRiMzEwNDhiZmI1ZjI4N2Y5YzU4OGM4MGNmOTlmNzJjZTUyOTcxZjU3Y2NkNzVmODUzNTg3OTcwYWM5NWQzNDZhYWNmMzY5OWVkN2IyYmIyMDY5ZTJiMmM5YjE1OTg2Mjc5ZGNiYTNlMTMwYjRkMTdkNTI0ZTVkMmE5MTYyZTUzM2JjNWRlODJmNDBjNTg2ZDc2ODk2MTU0NDE3NzBkOGMwNDRlZjhhNjFlNWM3Y2JkZGQzOWFmYmQ1MDllMjU2In0.i4W_pbOVP9Qb-kkNaari-2U1eWfPSZ6QfYubb6r2SzN1VK0xRe_YT6Zm8gIuEoq8mf5p9wKPcsqzgJwLe27rGNTypCI9qZhVGqY0bNEC5GaXjH3YCXGI_hRKfHiqGbRD8XN1uhOlyWJg0pw_7DA4hdy1pGapw11Pu10y1-YMy6dlieAAU3ot87OGSr5bpXi3P3Wzgvv_QHRRn0ZVXHwp9p1UvG8LFkfzAg5lPqwQGZwMhqmp2NKSF_pStmzcKIsox_1ogrfam_3cm7p1iSRPMROYWxU9rwaOLQiXYXHuB1kO9Z62vxRJLySX_1PunWwXohbu4Rw7biBvpTdLI9D_DQThe token will decode to something like this:
The Header:
{
"typ": "JWT",
"alg": "RS256"
}The Payload:
{
"applicationVersion": "1.2.7",
"sub": "1-FgW7/lhAajlonnWAr7g3yB7eByYVkiV8O3UzsFPhEkoOYdr+bbeGeATwKyZUM6YenuUQb85G+PIijAxmP85GRnTIX6bdOdeJuuw=",
"application": "hatappstaging",
"iss": "postman.hubat.net",
"exp": 1543692303,
"iat": 1541100303,
"jti": "1c73175cd84624efb3ead7ea21fb055ae6f95a519722d314927f251dd13d19aac438861c441ef255a33dae1e1762ee914070251998cbc723a1e2f03f47784470cf70bb6aa003e582e0226d5d8a116af362d9e522a9b29b8281ab2014cc3ae4808e55a6e4752634b3f5b4c4a37e105f57695c6def44e77a2db8e5c9f36a768749"
}The key parts of the Payload are:
The
applicationVersionis the version of the app on the PDAThe
sub(subject) is the subject of the tokenThe
applicationis the application name that requested the tokenThe
iss(issuer) is the address of the PDA that has created the token and that you should be logging inThe
exp(expiry) time of the token as a Unix timestamp, defining whether the token is still validThe
iat(issued at time) time that the token has been created as a Unix timestamp, defining whether or not the token is still valid. Token expires after 30 days of the issue date regardless of whether or not a refreshed token has been received from the PDA.The
jti(JWT ID) is the ID of the token
Also the Signature, which is generated from the token and the private key of the PDA. The signature must be verified to confirm that the token has not been tampered with. A PDA’s public key can be accessed at the /publickey endpoint of the PDA (e.g. https://postman.hubat.net/publickey). The precise handling of tokens with asymmetric keys will depend on your library, however you need to make sure that your library supports RS256 keys.
jwt.io contains a very useful tool for token debugging while in development as well as listing all the major JWT libraries that you can use in your project.
When you have received a successful redirect from the PDA you can check with HAT for iOS and verity the user. To do so you simply have to call:
HATLoginService.loginToHATAuthorization(
applicationName: Auth.serviceName,
url: url,
success: success,
failed: failed)applicationNameis the name of the application that sent the user to log inurlis the full url that returned from thePDA, like the example at the beginning of step 3successis a callback to execute when the library has successfully authorised the user. You can use this callback to dismissSFSafariViewController, save the values needed and navigate to the nextUIViewController.failedis a callback to execute when the library couldn't authorise the user. You can use this callback to dismissSFSafariViewControllerand show an error message to the user.
Having received the success callback you have to save the token. ALWAYS use the Keychain to save the token. DO NOT save it in UserDefaults or in any non-encrypted database. One very nice library to use to write/read on Keychain is Keychain-swift. It's a good idea to also save the full PDA Address, as you're going need it many times to communicate with the PDA.
As soon as you save the token you are free to navigate to your next UIViewController.
Fail callback
If the authentication failed, you will be redirected to the fallback url. In that case you should dismiss SFSafariViewController and then update the UI or show an error message back to the user.
To dismiss Safari you do it from the viewController that originally presented the SFSafariViewController, like this:
self.safariVC?.dismiss(animated: true, completion: nil)
self.safariVC?.removeFromParent()Last updated
Was this helpful?