2

I have successfully implemented two-factor-auth package to my web app however I would like to display QR code to a template when a user is logged in but am unable to do so as it stands.

This package uses wizard forms and when a user is prompted to setup two factor the QR code is displayed during setup for them to scan on their chosen device but not sure how to use the QR code for later use in another template.

I found the follwing piece of code from the wizard template which I tried to use but says page not found:

<div class="d-flex justify-content-center">
  <p><img src="{{ QR_URL }}" alt="QR Code" /></p>
</div>

Page not found error

 Using the URLconf defined in wfi_workflow.urls, Django tried these URL patterns, in this order:

    admin/
    account/login/ [name='login']
    account/two_factor/setup/ [name='setup']
    account/two_factor/qrcode/ [name='qr']

The current path, account/two_factor/qrcode/, matched the last one. 

But I can view the QR code for users via Admin panel under:

  • Otp_Totp
  • TOTP devices
  • Click on user and QRCode link is at the bottom of page

Anyone know how to go about displaying the QR code only in another template? If more info is required do let me know. Thanks

Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129
rob
  • 143
  • 1
  • 9

3 Answers3

0

To display QR code in template, you can get the image url in view like this:

device = TOTPDevice.objects.get(user=obj)
if device:
    qr_code_url = reverse('admin:%s_%s_qrcode' % (TOTPDevice._meta.app_label, TOTPDevice._meta.model_name), args=[device.pk])

or directly svg image:

device = TOTPDevice.objects.get(user=obj)
if device:
    import qrcode
    import qrcode.image.svg
    img = qrcode.make(device.config_url, image_factory=qrcode.image.svg.SvgImage)
Bodzaro
  • 1
  • 2
  • You'll need to do something with that image to make it renderable in a template, as shown in my answer: https://stackoverflow.com/a/73567883/6619548 – alstr Sep 01 '22 at 10:32
0

To incorporate the QR code into a template, you need to create it as a base 64-encoded image and pass it to your template in the context data:

views.py

import qrcode
from io import BytesIO
from base64 import b64encode

qr_code_img = qrcode.make(device.config_url)  # This should be the device for which you want to generate the QR code
buffer = BytesIO()
qr_code_img.save(buffer)
buffer.seek(0)
encoded_img = b64encode(buffer.read()).decode()
qr_code_data = f'data:image/png;base64,{encoded_img}'

return render(request, 'template.html', {'qr_code_data': qr_code_data})

template.html

<img src="{{ qr_code_data }}" />
alstr
  • 1,358
  • 18
  • 34
0

You can display QR code in Django Templates with the code below. *I use Django Two-Factor Authentication:

# "views.py"

from django.shortcuts import render
from django_otp.plugins.otp_totp.models import TOTPDevice
import qrcode
from io import BytesIO
from base64 import b64encode

def test(request):
    obj = TOTPDevice.objects.get(user_id=request.user.id)
    qr_code_img = qrcode.make(obj.config_url)
    buffer = BytesIO()
    qr_code_img.save(buffer)
    buffer.seek(0)
    encoded_img = b64encode(buffer.read()).decode()
    qr_code_data = f'data:image/png;base64,{encoded_img}'
    return render(request, 'index.html', {'qr_code_data': qr_code_data})
{% "index.html" %}

<img src="{{ qr_code_data }}" />
Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129