Sunday, May 24, 2020

Building REST APIs with FLASK Python Web Services- CRUD Application with User Authentication

User Authentication 

So once we have all our routes in place and we need to add in user authentication to ame sure only logged-in users can access certain routes. So now we will add in user login
and signup routes but before we need to add schema.

Create users.py:

In schema add two static methods to encrypt the password and verify password and for the same we will need a python library called "passlib".

just install this library by using the below command.

(venv)$ pip install passlib

Let's write the required code.

from api.database import db
from passlib.hash import pbkdf2_sha256 as sha256
from marshmallow_sqlalchemy import ModelSchema
from marshmallow import fields

class User(db.Model):
     _tablename_ = 'users'
 
  id = db.Column(db.Integer,primary_key=True)
  username = db.Column(db.String(120),unique = True,nullable = False) 
  password= db.Column(db.String(120),nullable=False)
  
   
def create(self):
        db.session.add(self)
db.session.commit()
return self
    @classmethod
def find_by_username(cls,username):
    return cls.query.filter_by(username=username).first()
@staticmethod
    def generate_hash(password):
    return sha256.hash(password)
@staticmethod
    def verify_hash(password,hash):
    return sha256.verify(password,hash)
class UserSchema(ModelSchema):
     class Meta(ModelSchema.Meta):
       model = User
   sqla_session = db.session
id = fields.Number(dump_only=True)    
username = fields.String(required=True)
 
Next create users.py in routes directory and we will add user login and signup routes.

For user authentication across the application we will use JWT(JSON WEB TOKENS) authentication. In a flask, there is an opensource extension called Flask-JWT-Extended which
provides JWT support and other helpful methods.

Now install flask-JWT-Extended by using the following command.
(venv)$ pip install flask-JWT-Extended

@user_routes.route('/',methods=['POST'])
def create_user():
    try: 
    data = request.get_json()
data['password'] = User.generate_hash(data['password'])
user_schema = UserSchema()
user,error = user_schema.load(data)
result = user_schema.dump(user.create()).data
return response_with(resp.SUCCESS_201)
except Eception as e:
        print e
        return response_with(resp.INVALID_INPUT_422)
Now we will add a method for the signed-up users to login.

@user_routes.route('/login',methods=['POST'])
def authenticate_user():
    try: 
    data = request.get_json()
current_user = User.find_by_username(data['username'])
if not current_user:
     return response_with(resp.SERVER_ERROR_404)
 
if User.verify_hash(data['password'],current_user.password):
     access_token = create_access_token(identity=data['user_name'])
return response_with(resp.SUCCESS_201,value={'message':'Logged in as {}.format(current_user.username)'})
else:

             return response_with(resp.UNAUTHORIZED_401)
except Exception as e:
      print e
      return response_with(resp.INVALID_INPUT_422)   
  
The following code will take the username and password as input and verifies it. We have created a successful REST application with user authentication.









1 comment:

Anonymous said...

Kindly share the full code.