DEV Community 👩‍💻👨‍💻

Himanshu👓💻
Himanshu👓💻

Posted on • Updated on

My 100DaysOfCode Journal — Day03/04

Hey folks!

So it’s day 03 and day 04 of my 100daysofcode journal.

Here is a list of what we’ll be covering today:

  1. Features listing
  2. Login Implementation🤩
  3. JWT integration.

Features listing

Here is the list of features we’ll be introducing for our application.

Authentication: JWT

SMS: #twilio by @twilio

Email:@Mailchimp

Project Management: #Trello by @trello

Comments: custom

Payments: stripe by @stripe

Login Implementation

So continuing with our code last time, we’ll be implementing login credentials as below. You might see that I have given some facelift, i will be explaining at some point.

@app.route("/api/v1/login", _methods_=['POST', 'GET'])

def login():
user = mongo.db.users
username = request.json['username']
password = request.json['password']
for user_details in user.find():
if user_details['username'] == username and bcrypt.check_password_hash(user_details['password'], password):
access_token = create_access_token(_identity_=username)
return make_response({'code': 200, 'access_token': access_token, "Message": "Ok"})
return make_response({'code': 404, 'Message': "User Not Found, would you like to create one?"})

The code is at followng URL :

https://github.com/aidataguy/pyguy/tree/Part3

So let me walk you through the code. Here, we will be defining our route for login. I have made URL’s a bit unique by making it something like:

/api/v1/login

Below I’ve defined the login url with GET and POST both. I

@app.route("/api/v1/login", _methods_=['POST', 'GET'])

So, next we’ll define the user table object and username which we’ll be getting from request(Postman)

def login():

user = mongo.db.users

username = request.json['username']

password = request.json['password']

Next, we’ll loop through existing users in table to find if the user exists. Also, before doing that, we’ll install following packages

flask_bcrypt & flask by running following command

pip install flask-jwt-extended flask-bcrypt

Then we would need to add definition at top of the our backend/app.py

from flask_pymongo import PyMongo

from flask_bcrypt import Bcrypt

Now that we have that sorted, we’ll loop through the user detail in users table. We are checking if the username and password do exists in the database. We’re using .check_password_hash method of bcrypt. You can check out the bcrypt the here

for user_details in user.find():  
if user_details[‘username’] == username and bcrypt.check_password_hash(user_details[‘password’], password):  
access_token = create_access_token(_identity_=username)  
return make_response({‘code’: 200, ‘access_token’: access_token, “Message”: “Ok”})  
return make_response({‘code’: 404, ‘Message’: “User Not Found, would you like to create one?”})

Awesome!! we have the login implemented. But before we could actually check this, we have to do changes to our register method. So here are changes I have implemented. I have implemented a new_user_creation method which we can be used anywhere in app.

def new_user_creation():
user = mongo.db.users
gen_hashpass = bcrypt.generate_password_hash(request.json['password'])
user.insert(
{'username': request.json['username'], 'password': gen_hashpass})
session['username'] = request.json['username']

The bcrypt’s generate_password_hash method actually helps in generating hash passwords and than with help of our check_hash_password method we can do comparison later on in Login method

JWT integration

We’ll introduce JWT extended in our application like so. Update the import and app configs to something like this in app. py . Also, we’ve introduced JWT_SECRET_KEY & app_secret key which will be used JWT. Additionally, we used JWTManager(app) so JWTManager can be used across the app.

'''Flask App For PyGuy WebSite'''
from flask import (Flask, jsonify, render_template,
request, session, make_response)
from flask_jwt_extended import (
JWTManager, jwt_required, create_access_token,
)
from flask_pymongo import PyMongo
from flask_bcrypt import Bcrypt

App Definitions & Configs

app = Flask(__name__, _root_path_='../frontend')
bcrypt = Bcrypt(app)
jwt = JWTManager(app)
app.config["MONGO_DBNAME"] = 'pysite'
app.config["MONGO_URI"] = "mongodb://localhost:27017/pysite"
app.secret_key = 'dawudawudbawbfawbfawc3241241j1jnjkjkn141nj4'

app.config['JWT_SECRET_KEY'] = "dawudawudbawbfawbfawc3241241j1jnjkjkn141nj4"

mongo = PyMongo(app)

You can read more about JWT-Extended here.

Every aspect of JWT based authentication is based on access tokens. So what we would be needing here is implement an protected method that would do all the heavy lifting in terms of providing and validating access_token. So let’s walk through the current code below.

@app.route(“/protected”, _methods_=[“GET”])  
@jwt_required  
_def_ protected():  
current_user = get_jwt_identity()  
return make_response({‘code’: 200, “logged_in_as”: current_user})

We are defining a GET method for protected route, which would use jwt_required method, and next we defined the method. Current user is set to get_jwt_identity, which will get the identity of the user. If it’s true, we’ll send a response.

Now in order to get the access token we have to make changes to our login method. So after looping through the users, we will create access token by setting the identity as username, because username is the entity that we would like access token to be generated for. If all is successful, we will make a response sending access token and 200 code.

@app.route("/api/v1/login", _methods_=['POST', 'GET'])

def login():
user = mongo.db.users
username = request.json['username']
password = request.json['password']
for user_details in user.find():

**if user_details['username'] == username and bcrypt.check_password_hash(user_details['password'], password):**

**access_token = create_access_token(_identity_=username)**

**return make_response({'code': 200, 'access_token': access_token, "Message": "Ok"})**

return make_response({'code': 404, 'Message': "User Not Found, would you like to create one?"})

Voila!! we’ve created access token and authenticated our user too 😎

POSTMAN TIME!!

Now, we shall test our JWT implementation. You can open postman and first do a register call to register a new user with that will use our bcrypt implementation once user is created, for login request url add localhost:5000/api/v1/login then in Body -> raw (select JSON from dropdown) and paste your registered user context like so :

{  
 "username": "admin",  
 "password": "b lalala Password"  
}

Refer to the below image in case you aren’t sure.

That’s all folks!! we’ve successfully implemented JWT & Bcrypt.

Top comments (0)

Build Anything...


Use any Linode offering to create something for the DEV x Linode Hackathon 2022. A variety of prizes are up for grabs, inculding $1,000 USD. 👀

Join the Hackathon <-