hatCluster – The HAT's cluster for the login. In this case we are using '.hubat.net' for testing purposes only. For production you'd use a real non-dev-sandbox PDA
hatApiVersion – The API version of the HAT
secure – If you want to run the HAT locally, you have to modify this field to 'false'
For better user experience, it's good practice to validate the user's input and navigate them to their PDA to Login only if their username is valid and exists. Otherwise we'll display an error message to inform the user about the issue. You can use the HAT-JS to check if a PDA with this username exists.
Let's create the redirectValidUser method to redirect an existing user. We can use the hat-js to check if the user exists:
// src/features/Login/LoginPage.js
import React, { useState } from 'react';
import { HatClient } from '@dataswift/hat-js';
import { isHatName } from "../../utils/validations";
import { appConfig } from "../../app.config";
function LoginPage() {
const [username, setUsername] = useState('');
const [errorMsg, setErrorMsg] = useState('');
const errorMessages = {
usernameNotValid: 'Sorry, this username is not valid',
usernameNotRecognised: 'Sorry, this username is not recognised'
};
const redirectValidUser = async (username) => {
try {
const hat = new HatClient({});
const hatDomain = username + appConfig.hatCluster;
// Use the hat-js's helper method to check if the user exists
const res = await hat.auth().isDomainRegistered(hatDomain);
// if the res is true, navigate the user to their PDA
if (res) {
const hatUrl = `https://${hatDomain}`;
const redirectUrl = `http://${window.location.host}/authentication`;
const fallback = `http://${window.location.host}/authentication`;
const applicationId = appConfig.applicationId;
window.location.href = hat.auth().generateHatLoginUrl(hatUrl, applicationId, redirectUrl, fallback);
} else {
// Display an error message when the username is not recognised
setErrorMsg(errorMessages.usernameNotRecognised);
}
} catch (e) {
console.log(e);
}
};
const validateLoginDetails = () => {
if (isHatName(username)) {
// Use the new method when the username is valid
redirectValidUser(username);
} else {
setErrorMsg(errorMessages.usernameNotValid);
}
};
return (
<form>
.
.
</form>
);
}
Upon successful login, the HAT will verify if the application has been granted all the permissions it needs. If not, the HAT user will need to provide these permissions for the app to access their HAT.
Lastly, the user will be redirected back to our application with the authentication token attached. This should be stored for subsequent API calls:
To collect the token parameter, we will need to create a new component in the Login feature
Create the authentication handler
In this example we will store the token value in the Session Storage. Upon successful login we will navigate the user back to the HomePage where we will need to add a different screen to display to the user when they are authenticated. In case of error, we will redirect the user back to the Login page.
// src/features/Login/AuthenticationHandler.js
import React, { useEffect } from 'react';
import { useHistory } from 'react-router';
import { getParameterByName } from "../../utils/windowHelper";
function AuthenticationHandler() {
const history = useHistory();
useEffect(() => {
const token = getParameterByName('token');
const error = getParameterByName('error');
if (error) {
history.push('/login');
}
if (token) {
sessionStorage.setItem('token', token);
history.push('/');
}
}, [history]);
return <div>Loading...</div>;
}
export default AuthenticationHandler;
Get parameter by name
In order to get the query parameter value, let's create a new function getParameterByName in the utils/ folder:
// src/utils/windowHelper.js
export const getParameterByName = variable => {
const query = window.location.search.substring(1);
const vars = query.split('&');
for (let i = 0; i < vars.length; i++) {
const pair = vars[i].split('=');
if (pair[0] === variable) {
return decodeURIComponent(pair[1]);
}
}
return null;
};
Import the function in the AuthenticationHandler.js:
// src/features/Login/AuthenticationHandler.js
import { getParameterByName } from "../../utils/windowHelper";