Testing Iframe Authentication

Prev Next

The guide offers a way to test the iframe authentication flow within Rocket.Chat. We will use a test tool built by the Rocket.Chat team. This can serve as an example of how to set up iframe auth calls to Rocket.Chat.

Prerequisites

  • A Rocket.Chat instance running locally at localhost:3000

  • Node.js and npm installed

This test tool is designed for your localhost enviroment.

Clone and set up test service

  1. Clone the GitHub repository for the iframe-auth-example test service using the following command:

git clone https://github.com/RocketChat/iframe-auth-example.git
  1. Enter the project directory (using the cd iframe-auth-example command).

  2. In the project directory, open the index.js file and update it. Paste the following code (note that the user credentials and the Rocket.Chat URL are hardcoded in this file):

var express = require('express');
var bodyParser = require('body-parser');
var axios = require('axios');
var fs = require('fs');

var app = express();

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

// CORS in case you need
// app.use((req, res, next) => {
	// res.set('Access-Control-Allow-Origin', 'http://localhost:3000'); // this is the rocket.chat URL
	// res.set('Access-Control-Allow-Credentials', 'true');

// 	next();
// });

// this is the endpoint configured as API URL
app.post('/sso', function (req, res) {

	// add your own app logic here to validate user session (check cookies, headers, etc)

	// if the user is not already logged in on your system, respond with a 401 status
	var notLoggedIn = false;
	if (notLoggedIn) {
		return res.sendStatus(401);
	}

	// you can save the token on your database as well, if so just return it
	// MongoDB - services.iframe.token
	var savedToken = null;
	if (savedToken) {
		return res.json({
			token: savedToken
		});
	}

	// if dont have the user created on rocket.chat end yet, you can now create it
	var currentUsername = null;
	if (!currentUsername) {
		axios.post('http://localhost:3000/api/v1/users.register', {
			username: 'new-user',
			email: 'mynewuser@email.com',
			pass: 'new-users-passw0rd',
			name: 'New User'
		}).then(function (response) {

			// after creation you need to log the user in to get the `authToken`
			if (response.data.success) {
				return axios.post('http://localhost:3000/api/v1/login', {
					username: 'new-user',
					password: 'new-users-passw0rd'
				});
			}
		}).then(function (response) {
			if (response.data.status === 'success') {
				res.json({
					loginToken: response.data.data.authToken
				});
			}
		}).catch(function (error) {
			res.sendStatus(401);
		});
	} else {

		// otherwise create a rocket.chat session using rocket.chat's API
		axios.post('http://localhost:3000/api/v1/login', {
			username: 'new-user',
			password: 'new-users-passw0rd'
		}).then(function (response) {
			if (response.data.status === 'success') {
				res.json({
					loginToken: response.data.data.authToken
				});
			}
		}).catch(function() {
			res.sendStatus(401);
		});
	}
});

// just render the form for the user authenticate with us
app.get('/login', function (req, res) {
	res.set('Content-Type', 'text/html');
	fs.createReadStream('login.html').pipe(res);
});

// receives login information
app.post('/login', function (req, res) {

	// do your own authentication process

	// after user is authenticated we can proceed with authenticating him on rocket.chat side

	//
	//
	// the code bellow is exact the same as the on /sso endpoint, excepts for its response
	// it was duplicated since the purpose of this is app is for helping people understanding
	// the authentication process and being a well designed app =)
	//
	//

	// if dont have the user created on rocket.chat end yet, you can now create it
	var currentUsername = 'new-user';
	if (!currentUsername) {
		axios.post('http://localhost:3000/api/v1/users.register', {
			username: 'new-user',
			email: 'mynewuser@email.com',
			pass: 'new-users-passw0rd',
			name: 'New User'
		}).then(function (response) {

			// after creation you need to log the user in to get the `authToken`
			if (response.data.success) {
				return axios.post('http://localhost:3000/api/v1/login', {
					username: 'new-user',
					password: 'new-users-passw0rd'
				});
			}
		}).then(function (response) {
			if (response.data.status === 'success') {

				// since this endpoint is loaded within the iframe, we need to communicate back to rocket.chat using `postMessage` API
				res.set('Content-Type', 'text/html');
				res.send(`<script>
				window.parent.postMessage({
					event: 'login-with-token',
					loginToken: '${ response.data.data.authToken }'
				}, 'http://localhost:3000'); // rocket.chat's URL
				</script>`);
			}
		}).catch(function (error) {
			res.sendStatus(401);
		});
	} else {
		// otherwise create a rocket.chat session using rocket.chat's API
		axios.post('http://localhost:3000/api/v1/login', {
			username: 'new-user',
			password: 'new-users-passw0rd'
		}).then(function (response) {
			if (response.data.status === 'success') {

				// since this endpoint is loaded within the iframe, we need to communicate back to rocket.chat using `postMessage` API
				res.set('Content-Type', 'text/html');
				res.send(`<script>
				window.parent.postMessage({
					event: 'login-with-token',
					loginToken: '${ response.data.data.authToken }'
				}, 'http://localhost:3000'); // rocket.chat's URL
				</script>`);
			}
		}).catch(function() {
			res.sendStatus(401);
		});
	}
});

app.listen(3030, function () {
  console.log('Example app listening on port 3030!');
});
  1. Save the index.js file.

  2. Run the following commands to start the project:

npm install
npm start

You should get a response like this: Example app listening on port 3030!

Configure Rocket.Chat settings

  1. In your local Rocket.Chat workspace, go to Manage > Workspace > Settings > Accounts > Iframe.

  2. Toggle on the Enabled setting.

  3. Add the IFrame URL value as http://localhost:3030/login.

  4. Enter the API URL value as http://localhost:3030/sso.

  5. Enter the Api Method value as POST. The following screenshot shows the settings and the values:

  1. Save the changes.

Test the authentication

  1. Open an incognito window in your browser and access the local Rocket.Chat instance.

  2. You should see the custom login page instead of the default login page.

  3. Enter the hardcoded user credentials from the index.js file:

    1. Username: new-user

    2. Password: new-users-passw0rd

  4. Click Submit. You should now be logged in to your workspace.

Change the currentUsername to ' true' at line 105 in the index.js file to enable re-login with the same user. Note that modifying the code allows any existing Rocket.Chat user to be used.

To learn more, see this pull request.

Once the iframe-auth-example service runs, the iframe authentication calls are executed. It returns unauthorized error if the credentials are not valid.

By following the outlined steps and leveraging the provided test tool, you can confirm the successful integration of iframe authentication into your Rocket.Chat setup. If you want to make additional tests, you can modify the index.js file according to your needs.