Generate a QRCode on your smartphone with your Google account and use it to unlock a door.
Few days ago, with @loicdesroc, we talk about new solutions to open doors (especially for professional purposes). At please-open.it, we have a solution based on bluetooth communication, the user’s smartphone acting like a remote control. We exposed that here :
Have you tried an onboarding pass on your smartphone in the airport ? Something like this :
A QRcode is very easy to read with a simple camera.
In this post, we will provide you instructions how to build a such system for a door, using a raspberry pi and an usb camera.
It is based on oauth2 tokens. In this example, we built something using Google Account. You can do the same with any oauth2 provider (github, facebook, twitter…). For specific needs, we built a backend at please-open.it with special features like calendar restrictions on accounts. For your professional needs, write us an email : contact@please-open.it
We use a simple relay module like this :
VCC goes on 2
GND on 6
IN on 16 (gpio 4).
A red led is soldered on 18 (+) and 20 (GND)
The relay drives an electric door lock like this :
With wiring pi, a simple command can drive all gpio on the pi : http://wiringpi.com/the-gpio-utility/
gpio mode 4 out;
gpio mode 5 out;
gpio write 4 0;
gpio write 5 0;
Then :
gpio write 4 1 ;
sleep 2 ;
gpio write 4 0 ;
Or :
gpio write 5 1 ;
sleep 2 ;
gpio write 5 0 ;
A simple web application will connect to your Google Account (with your authorization) and generates a QRcode containing your authentication token.
This token gives access to your first name, last name, email and profile picture only.
Oauth playground will help you understand how to use Google Oauth https://developers.google.com/oauthplayground
Follow this simple tuto : https://developers.google.com/identity/sign-in/web/sign-in
Don’t forget to register your application. We have done it, you can access it on https://login.please-open.it.
<html lang="en">
<head>
<meta name="google-signin-client_id" content="<youid>.apps.googleusercontent.com">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<script src="https://apis.google.com/js/platform.js" async defer></script>
</head>
<body>
<div class="g-signin2" data-onsuccess="onSignIn"></div>
<script>
function onSignIn(googleUser) {
var profile = googleUser.getBasicProfile();
console.log(googleUser.Zi.access_token)
console.log('Name: ' + profile.getName());
console.log('Image URL: ' + profile.getImageUrl());
console.log('Email: ' + profile.getEmail()); // This is null if the 'email' scope is not present.
}
</script>
</body>
</html>
DONE ! A token is generated.
There is multiple javascript libraries for QRCode generation.
First of all, we tried this library :
https://github.com/jeromeetienne/jquery-qrcode
It does the job, but we need more options for code generation. By default, this library generates a QR code with a medium redundancy. So the code needs to store more informations and become difficult to read.
Example using unitag, 4 qrcodes containing the same informations with different redundancies :
Low :
Medium :
Quality :
Strong :
Why using redundancy ? It depends on :
Or put a logo in !
Those styles affects data, that’s why redundancy is needed. In your case, we want less redundancy.
This library has more parameters, including redundancy ! https://larsjung.de/jquery-qrcode/
So let’s generate a QRCode with it, containing a token :
$('#qrcode').qrcode({
render: 'canvas',
background: '#FFFFFF',
size: 300,
ecLevel: 'L',
text: googleUser.Zi.access_token
});
An example of usable page is available on https://login.please-open.it
Entire source code is available : https://github.com/please-openit/public-webapp-qrcode-app
Zbarcam is an opensource software available for various distributions :
https://www.systutorials.com/docs/linux/man/1-zbarcam/
Install it just with :
apt-get install zbar-tools
A raspberry pi is not powerful enough to analyse high definition images fluently, so I decided to decrease the resolution :
zbarcam --prescale=640x480
Use any qrcode generator (IE : https://www.qr-code-generator.com)
and test your camera. You will probably need to adjust focus.
zbarcam output qrcode content like this : qrcode:"content or your qr code"
openID provides a set of services behind some URL described in a “discovery document”.
Google has one, described here : https://developers.google.com/identity/protocols/OpenIDConnect#discovery
An HTTP GET to https://www.googleapis.com/oauth2/v3/userinfo with the token in an “Authorization” header will return a json object with informations about the user.
curl -X GET https://www.googleapis.com/oauth2/v2/userinfo -H 'Authorization: Bearer '$token
We have a JSON structure with user informations. We extract the email using jq :
apt-get install jq
jq -r .email
(-r removes double quotes)
Then, a simple “grep” in a text file to verify if the email is present. WC will count number of output lines
count=$(grep $email emails.txt | wc -l)
A simple if terminates the job :
if [ $count = 1 ]; then
// account is authorized
else
// forbidden
fi
done;
Still in the discovery document : https://developers.google.com/identity/protocols/OpenIDConnect#discovery
And endpoint is dedicated for token revocation. It takes a token in parameter in a GET request.
curl -H https://accounts.google.com/o/oauth2/revoke?token=$token
#!/bin/bash
gpio mode 4 out;
gpio mode 5 out;
gpio write 4 0;
gpio write 5 0;
while : ; do
read token
token=$(echo $token | cut -d':' -f2)
email=$(curl -X GET https://www.googleapis.com/oauth2/v2/userinfo -H 'Authorization: Bearer '$token | jq -r .email)
count=$(grep $email emails.txt | wc -l)
if [ $count = 1 ]; then
gpio write 4 1 ;
sleep 2 ;
gpio write 4 0 ;
curl -H https://accounts.google.com/o/oauth2/revoke?token=$token
else
gpio write 5 1 ;
sleep 2 ;
gpio write 5 0 ;
fi
done;
We put the command line in a bash script, in case we need to adjust some variables or add logs redirection :
please-open-it.sh
#!/bin/bash
/usr/bin/zbarcam --nodisplay --prescale=640x480 /dev/video0 | bash /home/pi/decode_token.sh
please-open-it.service
[Unit]
Description=Please Open It Service
After=network.target
[Service]
Type=simple
WorkingDirectory=__WORKING_DIRECTORY__
ExecStart=/home/pi/please-open-it.sh
StandardOutput=journal
[Install]
WantedBy=multi-user.target
Then install the service using systemd
systemctl enable please-open-it.service
systemctl start please-open-it.service
Entire source code is available : https://github.com/please-openit/embedded-qrcode-app
Door lock is screwed on the case. A big nut ensure the locking system.
A USB camera (standard HD webcam) is glued on the left side. The focus is adjusted for the distance between the phone on the glass and the lens.
We have developped a platform that implements many functionnalities on top of oauth protocol, like calendar restrictions or pay by use. This plateform is design to work with any oauth provider. It means if your team has Gsuite accounts you can manage physical access to offices without any card, badge etc... Just a smartphone and an account on your existing infrastructure.
If you are interested, please send us an email : contact@please-open.it