برنامه نویسی

هش رمز عبور با استفاده از Bcrypt در پایتون

سلام، علاقه مندان به فناوری!

من راه خود را از طریق بوت کمپ مدرسه Flatiron برای مهندسی نرم افزار طی می کنم. باورش سخت است که من اکنون 80 درصد از مسیرم را طی کرده ام و به پروژه نهایی خود نزدیک می شوم. تا کنون جاوا اسکریپت، ری اکت، پایتون و فلاسک را یاد گرفته‌ام و به‌تازگی اولین پروژه پر پشته‌ام را به پایان رساندم. پروژه نهایی من قرار است ابزاری برای دانش‌آموزان باشد تا در کلاس ریاضی از آن استفاده کنند تا انجام تکالیف با نمودار را در رایانه آسان‌تر کند. من می‌دانم که می‌خواهم به کاربرانم اجازه بدهم یک حساب برای ذخیره کار خود داشته باشند، بنابراین هش رمز عبور را با استفاده از bcrypt پیاده‌سازی خواهم کرد. این یک سطح امنیتی را برای کاربران اضافه می کند زیرا رمزهای عبور آنها قبل از ذخیره آنها در جدول کاربری من رمزگذاری می شود. از آنجایی که بسیاری از افراد از رمزهای عبور برای حساب‌های مختلف استفاده مجدد می‌کنند، مهم است که من سهم خود را انجام دهم تا مطمئن شوم رمز عبور آنها توسط شخصی که از آن برای مقاصد غیراخلاقی استفاده می‌کند کشف نمی‌شود.

چه در برنامه نویسی تازه کار باشید و چه یک توسعه دهنده باتجربه، درک نحوه پیاده سازی bcrypt در پایتون می تواند یک مهارت ارزشمند در جعبه ابزار شما باشد. پس بیایید شروع کنیم و نکات و نکات هش کردن رمز عبور با bcrypt در پایتون را بررسی کنیم!

هنگامی که درک خوبی از استفاده از bcrypt پیدا کردید، قویاً شما را تشویق می کنم که نمک را به هش خود اضافه کنید. کمی بعد برگردید و من یک پست وبلاگ اضافی در مورد افزایش امنیت ذخیره سازی رمز عبور با نمک اضافه می کنم!


*اهداف:
*
– اضافه کردن هش رمز عبور به جداول SQLAlchemy در حال اجرا در Flask (Python)

*دانش پیشین:
*
– ایجاد جداول در SQLAlchemy (یادآوری ارائه شده است)

  • با استفاده از PostMan
  • واردات کتابخانه ها
  • راه اندازی سمت سرور یک برنامه

*قسمت 1) تاسیسات:
*

Bcrypt یک بسته نصبی است که می توانید از طریق خط فرمان نصب کنید. اگر از پایتون استفاده می کنید، از خط فرمان زیر استفاده کنید:
$ pipenv install bcrypt

من از یک چارچوب Flask استفاده می کنم، بنابراین نسخه Flask bcryt را نصب خواهم کرد:

$ pipenv install flask-bcrypt

اکنون که bcrypt را در فایل پیپ خود دارید، کلید مخفی خود را با ارسال عبارت زیر در خط فرمان ایجاد کنید:

$ python -c 'import os; print(os.urandom(16))

این کلیدی است که برنامه شما برای رمزگذاری رمز عبور هنگام اضافه شدن به پایگاه داده استفاده می کند. به طور مشابه، دفعه بعد که کاربر سعی می کند وارد سیستم شود، از کلید مخفی برای رمزگشایی رمز عبور استفاده می شود. شما به زودی به این رشته از کاراکترهای تصادفی نیاز خواهید داشت!

*قسمت 2) فایل پیکربندی
*

من شخصاً دوست دارم یک فایل config.py داشته باشم تا از شلوغی در models.py خود بکاهم. این فضایی است برای رسیدگی به تمام متن‌های وارد شده و ابرداده شما. این چیزی است که من در config.py دارم:

from flask import Flask
from flask_bcrypt import Bcrypt
from flask_migrate import Migrate
from flask_restful import Api
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import MetaData
from flask_cors import CORS


app = Flask(__name__)
app.secret_key = b'<<This is where your secret key string goes>>'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.json.compact = False

metadata = MetaData(naming_convention={
    "ix": "ix_%(column_0_label)s",
    "uq": "uq_%(table_name)s_%(column_0_name)s",
    "ck": "ck_%(table_name)s_`%(constraint_name)s`",
    "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
    "pk": "pk_%(table_name)s"
    })
db = SQLAlchemy(metadata=metadata)

migrate = Migrate(app, db)
db.init_app(app)

bcrypt = Bcrypt(app)

api = Api(app)
CORS(app)
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

شما کلید مخفی را در فضای مشخص شده قرار می دهید.

لطفاً توجه داشته باشید که برخی از این واردات برای ایجاد جداول SQLAlchemy من هستند. تنظیمات لازم را برای پروژه خود انجام دهید.

*قسمت 3) مدل ها
*

من همیشه دوست دارم به مدل‌ها به‌عنوان چیزی که از داده‌هایم مدل‌سازی می‌کنم فکر کنم. اینجا جایی است که می خواهیم ساختار جداول خود را شکل دهیم. برای این مرحله، من فقط یک جدول کاربر بسیار ابتدایی را با نام کاربری و رمز عبور نشان می دهم.

در بالای فایل، واردات خود را مدیریت کنید.

from sqlalchemy.ext.hybrid import hybrid_property

from config import db, bcrypt
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

جدول کاربری خود را ایجاد کنید. شما رمز عبور را همانطور که کاربر تایپ کرده است ذخیره نخواهید کرد. در عوض، نسخه رمزگذاری شده رمز عبور او را ذخیره می کنید. برای تأیید این موضوع در جدول، از نام ستون “_password_hash” استفاده کنید.

class User(db.Model):
    __tablename__ = 'users'

    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String, unique = True, nullable = False)
    _password_hash = db.Column(db.String)
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اکنون زمان شروع هش کردن رمز عبور است. متن دیگ بخار زیر رمز عبور کاربر را رمزگذاری می کند، بنابراین جدول شما چیزی را ذخیره می کند که حتی شبیه آنچه در هنگام ثبت نام کاربر در سایت شما تایپ شده است، ندارد. هنگامی که کاربر سعی می کند دوباره به سیستم وارد شود، از کلید مخفی برای بررسی اینکه آیا ورودی رمز عبور به همان رشته ای از grarbildy goop منجر می شود استفاده می شود که در جدول ذخیره شده است.

class User(db.Model):
    __tablename__ = 'users'

    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String, unique = True, nullable = False)
    _password_hash = db.Column(db.String)

    @hybrid_property
    def password_hash(self):
        raise AttributeError('Password hashes may not be viewed.')

    @password_hash.setter
    def password_hash(self, password):
        password_hash = bcrypt.generate_password_hash(
            password.encode('utf-8')
        )
        self._password_hash = password_hash.decode('utf-8')

    def authenticate(self, password):
        return bcrypt.check_password_hash(
            self._password_hash, password.encode('utf-8')
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

*قسمت 4) برنامه
*

فایل app.py جایی است که ما در حال افزودن قابلیت به مسیرهای خود هستیم. بیایید روی ایجاد یک ‘POST’ برای کلاس Signup و یک ‘POST’ برای یک کلاس Login تمرکز کنیم. ما از Postman برای بررسی عملکرد کار استفاده خواهیم کرد.

(مثل همیشه!) با واردات مورد نیاز شروع کنید:

#!/usr/bin/env python3

from flask import request, session, make_response
from flask_restful import Resource
from sqlalchemy.exc import IntegrityError


from config import app, db, api
from models import User
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

قبل از اینکه خیلی جلوتر بروید، به models.py برگردید و جداول خود را بسازید. به عنوان یادآوری، اگر در فلاسک هستید، در اینجا خطوط فرمان وجود دارد.

# export FLASK_APP=app.py
# export FLASK_RUN_PORT=5555
# flask db init
# flask db revision --autogenerate -m 'Create tables' 
# flask db upgrade 
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

قبل از رفتن به مرحله بعد، مطمئن شوید که جدول کاربری شما در پایگاه داده شما نمایش داده می شود.

بیایید یک کلاس Signup ایجاد کنیم که بتواند یک کاربر جدید را به پایگاه داده ما ارسال کند.


class Signup(Resource):
    def post(self):

        request_json = request.get_json()

        username = request_json.get('username')
        password = request_json.get('password')

        user = User(
            username = username
        )

        user.password_hash = password

        try:
            db.session.add(user)
            db.session.commit()

            session ['user_id']=user.id

            print (user.to_dict(), 201)

        except IntegrityError:
            print ('nope')

            return {'error': '422 Unprocessable Entity'}, 422

api.add_resource(Signup, '/signup', endpoint="signup")

if __name__ == '__main__':
    app.run(port=5555, debug=True)
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

*قسمت 5) ساختن جادو اتفاق می افتد!
*

اکنون باید بتوانید به پستچی بروید و http://127.0.0.1:5555/signup POST را اجرا کنید. نام کاربری و رمز عبور را برای تست وارد کنید. اگر پس از اجرای یک POST پیام «تهی» دریافت کردید، تبریک می‌گوییم! توانجامش دادی!! اگر نه، تنظیم جدول خود را دوباره بررسی کنید. ممکن است یک اشتباه تایپی کوچک مانع شما شود.

توضیحات تصویر

برای بررسی اینکه آیا موفق هستید، به جدول خود در پایگاه داده خود بروید. شما باید یک ردیف جدید با نام کاربری به عنوان هر چیزی که وارد کرده اید و یک رشته مزخرف ببینید. این رمز عبور هش شده است.

برای بررسی عملکرد ورود به سیستم با رمز عبور هش شده خود، یک کلاس Login جدید در app.py اضافه کنید:

class Login(Resource):

    def post(self):

        request_json = request.get_json()

        username = request_json.get('username')
        password = request_json.get('password')

        user = User.query.filter(User.username == username).first()

        if user:
            if user.authenticate(password):
                print("authenticate")
                session['user_id'] = user.id
                return user.to_dict(), 200

        return make_response({'error': '401 Unauthorized'},401) 

api.add_resource(Login, '/login', endpoint="login")
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

به پستچی برگردید مسیر را به http://127.0.0.1:5555/login تغییر دهید و همان نام کاربری و رمز عبوری را که در ثبت نام استفاده کرده اید وارد کنید. شما باید یک شی با نام کاربری و رمز عبور هش شده را برگردانید.


موفق باشی! شما فقط با ایمن کردن گذرواژه‌هایشان در پایگاه داده خود به کاربران خود کمک کردید. اگر توانستید تا اینجا پیش بروید، پیشنهاد می‌کنم برای یک لایه امنیتی بیشتر به روش هش رمز عبور خود نمک اضافه کنید. من به زودی با یک پست وبلاگ در مورد نمک پیگیری خواهم کرد!

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا