Passwordless authentication - how and when to invalidate a login code

Instead of invalidating the login code when the link is clicked, have a script on the page that runs and makes a request to your server to invalidate the code. This will only be effective if the "mail scanner" just visits the page and doesn't run any scripts on it.

You should also invalidate the code after a period of time (your second option), because if the user is running a browser with scripts disabled the code will not be invalidated by this method. The timeout serves as a backup if this is the case.

If you find that whatever "mail scanner" your users have is running scripts on the page, this won't work. Instead, you could require a user action on the linked page to complete the login process. Your users would click the link in the e-mail and be taken to a simple page with a login button, and perhaps some text like Log in as <username>?. Only log them in (and invalidate the login code) when they click the button. This would require two clicks from your users instead of one, but I don't think that's too inconvenient.

Since the "mail scanner" will only visit the page and not click the button, it won't use up the code.

The more I think about it, the more I like requiring a click. It doesn't rely on the mail scanner not running scripts so it should be more robust. You could even combine it with Steffen Ullrich's cookie idea. If the user clicks the login link in the e-mail and has the cookie, you know they're not the mail scanner so you can log them in right away. One click and they're logged in. If the cookie is NOT present, the click might actually be coming from the mail scanner, so you show a page with a login button. If it's actually just the user on a different browser (or the same browser with cookies disabled), they'll click the button and log in. In this case it took them two clicks, but that's only a slight inconvenience and it's only necessary if the cookie isn't there.

See this similar question.

It is unclear in which context the password-less login is used. But, if the user gets send the link to login only after visiting the site, then you could issue a cookie to the users browser and expect this cookie when the user logs in.

Most users will likely use the same browser to login after getting the link via mail and in this case you could align the clicked URL with the cookie send by the browser. Since the security appliance has no knowledge of the end users cookies you can easily reject the click from this appliance.

In case the user uses a different browser for clicking the link or if the user has deleted the cookies explicitly or implicitly (like when using a new private browser session) you can still have an explicit token in the mail the user can manually enter to continue with the authentication.

This way almost all users are handled transparently when clicking the link, the remaining users can continue manually by entering the token and any automatic systems are left out - even if they are able to execute the Javascript on the page.

I would not count on the inability of these analysis systems to run script. I'm pretty sure that many will actually handle script since this is also a typical mechanism used in phishing mails to complicate analysis. Instead you should count on missing knowledge of the system (i.e. does not know the cookie) and not missing capabilities.

Log in only on POST request. The link in the email should not cause a login: it should simply link to a login page. The URL code can be extracted from the URL and put into a hidden form field. When the form is submitted, which the email scanner will not do, then, and only then, is the user logged in.

If you want to reduce user friction, you can have javascript submit the form automatically once the page loads.