Fork me on GitHub

Google Sign-in Tutorial

This tutorial demonstrates Google Sign-in integrated into WoOF.

Tutorial Source

Sign-in JavaScript

As per the Google Sign-in tutorial, Google sign-in is configured as follows.

Note that JQuery has been used. However, any supported web / mobile front-end technology can be used. See the OfficeFloor Subscription App for example (code available here).

<html>
<head>

<!-- Google Sign in -->
<script src="https://apis.google.com/js/platform.js" async defer></script>
<meta name="google-signin-client_id"
	content="388391303753-jqugo4vugcf4po6pbenk7879f8er39h2.apps.googleusercontent.com">

<!-- JQuery (but can be any other library) -->
<script src="https://code.jquery.com/jquery-3.3.1.min.js"
	integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
	crossorigin="anonymous"></script>

</head>
<body>

	<!-- Sign in -->
	<div class="g-signin2" data-onsuccess="onSignIn"></div>
	<div>
		<p id="name"></p>
		<img id="profile"></img>
		<p id="email"></p>
	</div>
	<script type="text/javascript">
		function onSignIn(googleUser) {
			var profile = googleUser.getBasicProfile();
			$('#name').text('Hi ' + profile.getName());
			$('#profile').attr('src', profile.getImageUrl());

			// Send google login token to server
			$.ajax({
				type : "POST",
				url : '/login',
				dataType : 'json',
				data : JSON.stringify({
					googleIdToken : googleUser.getAuthResponse().id_token
				}),
				contentType : 'application/json',
				success : function(result) {
					$('#email').text('Server retrieved email: ' + result.email)
				}
			})
		}
	</script>

	<!-- Sign out -->
	<p>
		<a href="#" onclick="signOut();">Sign out</a>
	</p>
	<script>
		function signOut() {
			gapi.auth2.getAuthInstance().signOut().then(function() {
				$('#name').text('');
				$('#profile').attr('src', '');
				$('#email').text('')
			});
		}
	</script>

</body>
</html>

This will use the Google sign-in features and send the Google Id Token to WoOF to login in the user. This is confirmed by displaying the user's email (sent back from the WoOF server).

Configuring Google Sign-in Integration

Google sign-in is configured in application.objects as follows:

<objects>

	<managed-object source="net.officefloor.identity.google.GoogleIdTokenVerifierManagedObjectSource">
		<property name="google.client.id" value="388391303753-jqugo4vugcf4po6pbenk7879f8er39h2.apps.googleusercontent.com" />
	</managed-object>

</objects>

This is used by the following service method to verify the user login and send back the email:

public class LoginLogic {

	@HttpObject
	@Data
	@AllArgsConstructor
	@NoArgsConstructor
	public static class LoginRequest {
		private String googleIdToken;
	}

	@Data
	@AllArgsConstructor
	public static class LoginResponse {
		private String email;
	}

	public void login(LoginRequest request, GoogleIdTokenVerifier tokenVerifier, ObjectResponse<LoginResponse> response)
			throws Exception {

		// Verify the token
		GoogleIdToken token = tokenVerifier.verify(request.getGoogleIdToken());

		// Send email response
		response.send(new LoginResponse(token.getPayload().getEmail()));
	}

}

Testing

To avoid having to call Google with real users, the following unit tests demonstrates creating mock tokens:

	@Order(1)
	@RegisterExtension
	public final GoogleIdTokenExtension googleSignin = new GoogleIdTokenExtension();

	@Order(2)
	@RegisterExtension
	public final MockWoofServerExtension server = new MockWoofServerExtension();

	@Test
	public void ensureLogin() throws Exception {

		// Create mock token
		String token = this.googleSignin.getMockIdToken("TEST", "mock@officefloor.net");

		// Ensure can login
		MockWoofResponse response = this.server
				.send(MockWoofServer.mockJsonRequest(HttpMethod.POST, "/login", new LoginRequest(token)));
		response.assertJson(200, new LoginResponse("mock@officefloor.net"));
	}

JUnit 4 example:

	private final GoogleIdTokenRule googleSignin = new GoogleIdTokenRule();

	private final MockWoofServerRule server = new MockWoofServerRule();

	@Rule
	public final RuleChain order = RuleChain.outerRule(this.googleSignin).around(this.server);

	@Test
	public void ensureLogin() throws Exception {

		// Create mock token
		String token = this.googleSignin.getMockIdToken("TEST", "mock@officefloor.net");

		// Ensure can login
		MockWoofResponse response = this.server
				.send(MockWoofServer.mockJsonRequest(HttpMethod.POST, "/login", new LoginRequest(token)));
		response.assertJson(200, new LoginResponse("mock@officefloor.net"));
	}

Next

The next tutorial covers using Google Firestore.