DEV Community

Cover image for TV Channel Website: Authenticate User
Sokhavuth TIN
Sokhavuth TIN

Posted on

TV Channel Website: Authenticate User

GitHub: https://github.com/Sokhavuth/TV-Channel
Vercel: https://khmerweb-tv-channel.vercel.app/login

Authenticating user is the process of checking and verifying to see if a given user was registered in the database or not. If he/she was registered, we can write code to allow him/her to get into the restricted areas on the website.

When a user is authenticated, we can create a session to save his/her user data on the cloud in Redis Enterprise database. And for security matter, we can encode user data in a JSON web token (JWT) before saving this token in Redis database on the cloud.

For the reference to the token, we can create a session id using uuid module from Python standard library and store it in a signed cookie. Doing so, the cookie can be seen but cannot be modified. Moreover, we can check to see whether a user was authenticated or not by using session id to pull the JWT from Redis database in order to decode it and see if a user data was encoded into the JWT or not. if the user was authenticated, he/she can go straight into the restricted areas without signing in again.

# routes/frontend/login.py

from bottle import Bottle, get, post, redirect
from controllers.frontend.login import Login


app = Bottle()
login = Login()

@app.get("/")
def getLogin():
    if(login.checkLogged()):
        return redirect("/admin/post")
    else:
        return login.getPage()


@app.post("/")
def postLogin():
    return login.postItem()


Enter fullscreen mode Exit fullscreen mode
# controllers/frontend/login.py

import config, copy, hashlib, jwt, uuid
from datetime import datetime, timezone, timedelta
from bottle import template, request, response, redirect
from models.user import User


class Login:
    def __init__(self):
        settings = copy.deepcopy(config.settings)
        self.setup = settings()
        self.redis = config.redis
        self.secret_key = config.secret_key
        self.user = User()


    def getPage(self):
        self.setup["pageTitle"] = "Log into Admin Page"
        self.setup["route"] = "/login"

        return template("base", data=self.setup)


    def checkLogged(self):
        sessionid = request.get_cookie('sessionid', secret=self.secret_key)
        encoded_jwt = self.redis.get(sessionid) 
        try:
            payload = jwt.decode(encoded_jwt, self.secret_key, algorithms=["HS256"])
            if(payload["user"]):
                return True
        except jwt.ExpiredSignatureError:
            return False


    def postItem(self):
        password = request.forms.getunicode('password')
        email = request.forms.getunicode('email')

        user = self.user.checkUser(email)

        if user:
            passw = hashlib.sha512(password.encode("utf-8") + user["salt"]).hexdigest()
            if(passw == user["password"]):
                self.setup["pageTitle"] = 'Post Page'

                payload = {"userid": user["id"], "role": user["role"]}
                exp = datetime.now(timezone.utc) + timedelta(seconds=60*60*24*15)

                myjwt = jwt.encode({"user": payload, "exp": exp }, self.secret_key, algorithm="HS256")
                sessionid = uuid.uuid4().hex
                self.redis.set(sessionid, myjwt)
                self.redis.expire(sessionid, 60*60*24*15)
                response.set_cookie('sessionid', sessionid, path='/', secret=self.secret_key)

                return redirect('/admin/post')
            else:
                self.setup["pageTitle"] = 'Log into Admin Page'
                self.setup['message'] = 'Your password is wrong!'
                self.setup['route'] = '/login'
                return template("base", data=self.setup)
        else:
            self.setup["pageTitle"] = 'Log into Admin Page'
            self.setup['message'] = 'Your Email is wrong!'
            self.setup['route'] = '/login'
            return template("base", data=self.setup)


Enter fullscreen mode Exit fullscreen mode
# models/user.py

import config, hashlib, uuid
from bottle import request


class User:
    def __init__(self):
        self.db = config.conndb()


    def createRootUser(self):
        raw_salt = uuid.uuid4().hex
        password = "xxxxxxxxxxxxxxxxxxx".encode('utf-8')
        salt = raw_salt.encode('utf-8')
        hashed_password = hashlib.sha512(password + salt).hexdigest()

        user = { 
            "id": uuid.uuid4().hex, 
            "title": 'Guest',
            "content": '',
            "thumb": '',
            "date": '',
            "role": 'Guest',
            "email": 'guest@khmerweb.app',
            "salt": salt,
            "password": hashed_password,
        }

        self.db["users"].insert_one(user)


    def checkUser(self, email):
        return self.db["users"].find_one({ 'email': email })


Enter fullscreen mode Exit fullscreen mode

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

πŸ‘‹ Kindness is contagious

Please leave a ❀️ or a friendly comment on this post if you found it helpful!

Okay