Skip to content

03. Custom SQRL Login page

DBADougE edited this page Nov 5, 2019 · 2 revisions

This page builds on the InMemory example to show how to use the middleware with a custom login page.

Why a custom login page?

The default page generated by the middleware is not styled and can't be modified. Most of you will want the login page style consistent with the rest of the website.

How do I create a custom login page?

Start with a new html page the example uses a .cshtml Razor page but you can use any form of html page. When you want to show a SQRL login make an ajax call to "/login-sqrl?Helper" (for example "https://localhost/login-sqrl?Helper") This will return a JSON object with these values:

{
    "url": "",
    "checkUrl": "",
    "cancelUrl": "",
    "qrCodeBase64": "",
    "OtherUrls": 
    {
        "url": "",
        "checkUrl": "",
        "cancelUrl": "",
        "qrCodeBase64": ""
    }
}

JSON break down

We will quickly break down each property in the JSON object.

url

This is the SQRL schema URL used when SQRL client is on the same device as the web browser to start the process of logging in.

Example:

sqrl://localhost/login-sqrl?nut={the nut value for this request}

checkUrl

This is the URL the page can use to poll for successful login checks and/or can be given to the sure to do a manual login check.

Example:

https://localhost/login-sqrl?check={the nut value for this request}

cancelUrl

This is the URL the user will be directed to if they cancel the login from the SQRL client. It can be added as an optional "can" parameter to the "url" property.

Example:

https://localhost/

Example of using it with "url"

<a href="sqrl://localhost/login-sqrl?nut={the nut value for this request}&can='https://localhost/'">SQRL Login</a>

qrCodeBase64

This is the QR code Base64 encoded ready to be used in an image tag. The QR code it the "url" property value as a QR code.

Example of usage

<img src="data:image/bmp;base64,{Base64 encoded image}" />

OtherUrls

This is an array of alternative paths that the server allows and will only be present if there are any The values for each property are the same as above just embedded within the array.

Why a JSON object

The use of JSON was used to allow for an easy a quick implementation for the developer while allowing the best flexibility

Once you have the JSON

Now you have the JSON you can show the user the link and/or the QR code it's up to you how you go about this there is a helpful example to show how we have tested this but there many ways you can do this.

Things to note

  • To use the middleware, you must make a request to your callback URL (default is "login-sqrl") with the parameter of "Helper"
  • The QR code image is already generated on the server but you could generate this yourself if you wish
  • You should poll the "checkUrl" to see if a user has logged in using a different device such as a smartphone
  • The login can be placed anywhere

Spoof Message

Some SQRL clients (notably the GRC SQRL client) show a spoof message unless we do a bit of extra work.

What we need to do it when a tag is clicked (in the onclick event) we want to fire off a request to the SQRL client that tells it to expect a request for this website.

How we do this is when the link is clicked, we wish to run some JavaScript that loads an image from the SQRL client which has a localhost server running under the URL of "http://localhost:25519".

Our suggestion is that you use the following code

var gifProbe = new Image();
gifProbe.onload = function() {
    //We will cover this bit next
};
gifProbe.onerror = function() {
    setTimeout( function(){ gifProbe.src = "http://localhost:25519/" + Date.now() + '.gif';}, 250 );
};
gifProbe.onerror();

This allows use to determine if the SQRL client exists on the system that the link was clicked on and that it can communicate with the SQRL client so that it can be given the ability to redirect the browser.

How the client gets the ability to redirect the browser is where the command is in the onload for the image we should put the following JavaScript code

document.location.href = "http://localhost:25519/"+ /*A base64 encoded URL that is the URL we put in the HREF*/;

This allows the SQRL client to carry out the correct process and allows it to redirect the browser when finished.

A helpful method to get you started is this

function CpsProcess(e){
	var gifProbe = new Image();
	gifProbe.onload = function() {
		document.location.href = "http://localhost:25519/"+ btoa(e.getAttribute("href"));
	};
	gifProbe.onerror = function() {
		setTimeout( function(){ gifProbe.src = "http://localhost:25519/" + Date.now() + '.gif';	}, 250 );
	};
	gifProbe.onerror();
}

Other ways to do it

These options are available if you have turned on EnableHelpers in the options for the middleware

HelpersPaths can be used to restrict when the middleware makes the following available use this to restrict how many NUTs and how regular the URLs are generated. If HelpersPaths is null, then all paths will have SQRL URLs generated even if you’re not using them.

HTML helpers

To get an "a" tag use this

@Html.SqrlLink(Request)

To get an "img" tag with the QR code use this

@Html.SqrlQrImage(Request)

Or you can do both at once by using

@Html.SqrlLinkAndImage(Request)

To use these helpers you will need to have a using in your views for SqrlForNet

@using SqrlForNet

In a standard app you can do this ether in the view you want it in or in the "_ViewImports.cshtml" file.

SQRL Provider

We have also provided a provider which can give you the raw data, to use this you will need to use one of the following:

SqrlUrlProvider.GetUrl(Request);
Request.SqrlUrl();
Response.SqrlUrl();


SqrlUrlProvider.GetQrData(Request);
Request.SqrlQrData();
Response.SqrlQrData();


SqrlUrlProvider.GetCheckMilliseconds(Request);
Request.SqrlCheckMilliseconds();
Response.SqrlCheckMilliseconds();


SqrlUrlProvider.GetCheckUrl(Request);
Request.GetCheckUrl();
Response.GetCheckUrl();

This will allow you to create other type of pages when you don't want to use the HTML helpers or the JSON.

Conclusion

In this page we have shown the request and response that can be used to create custom login pages for SQRL the example in the repository shows how this can be done in one specific way but the flexibility of this approach should allow developers to do almost endless approaches.

Clone this wiki locally