Storing user-specific data
repl.it Authentication API
We'll take a quick look at how we can fetch the repl.it user_name of a visitor to our web page, and store some data relevant to them in the replit db for use on subsequent visits of theirs.
The repl.it Authentication API can also provide us with the user_id (a unique numerical value) and their user_roles, such as 'Teacher', 'Moderator', etc.
Thanks to mat1 for their tutorial on this topic!
Security
Don't rely on this to protect any of your own or other users' sensitive information.
Code walkthrough
Let's take a look at the following example, which incorporates repl.it authentication and touches upon some other topics we've seen previously, including Flask, the replit database, Jinja templates, and the time module:
Accessing request headers
try:
user_name = request.headers['X-Replit-User-Name']
except:
user_name = None
auth = True if user_name else False
- we
tryto fetch the'X-Replit-User-Name'from the page request headers, which should be there if the user is currently authorized - if this fails, we set
user_nametoNoneand thus the subsequent conditional statement will evaluate toFalse
Logging the time and user
if auth:
now = time.strftime("%X %x", time.localtime())
-
if a
user_nameis found, we assign a string-formatted time tonow, based on the current time in the user's timezone. -
"%X %x"is an example of a strftime code; a useful list of these codes can be found at strftime.org
if user_name in db.keys():
visits = db[user_name]
visits.append(now)
else:
visits = [now]
db[user_name] = visits
- we check to see if there is a key in the
dbequal touser_name - if there is, we get the associated value (a list), and
.append()nowto it - if there isn't we create a new list with a single value of
now - we set the value in the
dbassociated with the keyuser_nameto our new or updatedvisitslist
Jinja template for loop
Look at templates/index.html:
<ul>
{% for visit in visits %}
<li>{{ visit }}</li>
{% endfor %}
</ul>
- underneath the
{% if auth %}statement we see a Jinjaforloop, which will create alist element in our page for eachvisitin thevisitslist passed to the template by therender_template()function inmain.py
Repl.it authorization button
<div>
<script authed="location.reload()" src="https://auth.turbio.repl.co/script.js">
</script>
</div>
- this Javascript code snippet results in a
Login with Replitbutton being shown
Customizing the button
Look at static/custom.css (which we've imported in templates/index.html):
button.replit-auth-button {
text-indent: -9999px;
line-height: 0;
}
- the button brought into the page by the script is assigned to a CSS class of
.replit-auth-button - this (perhaps hacky-looking) code visually 'removes' the original text from the button
button.replit-auth-button::after {
content: "Authorize...";
text-indent: 0;
display: block;
line-height: initial;
font-family: Cambria, serif;
padding: 3px;
}
::aftercreates a pseudo-element which adds what's in thecontentpropertyafterany other children in the selected element