<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های امیرحسین</title>
        <link>https://virgool.io/feed/@geek</link>
        <description>کسی که موسیقی متن لحظه‌هاش نیاز به تغییر داره</description>
        <language>fa</language>
        <pubDate>2026-06-17 05:32:59</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/19820/avatar/CkObCj.png?height=120&amp;width=120</url>
            <title>امیرحسین</title>
            <link>https://virgool.io/@geek</link>
        </image>

                    <item>
                <title>قرار دادن JWT token در قسمت Cookie در جنگو</title>
                <link>https://virgool.io/@geek/%D9%82%D8%B1%D8%A7%D8%B1-%D8%AF%D8%A7%D8%AF%D9%86-jwt-token-%D8%AF%D8%B1-%D9%82%D8%B3%D9%85%D8%AA-cookie-%D8%AF%D8%B1-%D8%AC%D9%86%DA%AF%D9%88-tqvub8r3pvyi</link>
                <description>شاید برای شماهم پیش اومده باشه برای ارتباط back با front و حفظ امنیت و جلوگیری از حملات XSS  بخواین توکن احراز هویت jwt رو توی کوکی و بعنوان HttpOnly cookie نگهداری کنین، خب برای این‌کار راه‌های زیادی هست و من توی این نوشته سعی کردم براتون مسیری رو که رفتم توضیح بدم (خودم هم ازین منبع استفاده کردم).شما میتونین کدهای این پروژه رو اینجا ببینین.اول از همه ایجاد یه venv و شروع یه پروژه جنگویی:virtualenv .venv --python=python3source .venv/bin/activatepip install djangodjango-admin startproject projmv proj JwtInCookiecd JwtInCookiepython manage.py startapp jwt_cookieخب حالا وقتشه یه سری نیازمندی رو نصب کنیم:pip install djangorestframeworkpip install django-cors-headerspip install djangorestframework-simplejwtوقتی جنگو یه پروژه رو ایجاد میکنه توی مسیر اصلی برنامه که اینجا proj هست یه فایل به اسم settings.py میسازه که لازمه کمی ویرایشش کنیم و موارد زیر رو بهش اضافه کنیم:INSTALLED_APPS = [
    &#039;django.contrib.admin&#039;,
    &#039;django.contrib.auth&#039;,
    &#039;django.contrib.contenttypes&#039;,
    &#039;django.contrib.sessions&#039;,
    &#039;django.contrib.messages&#039;,
    &#039;django.contrib.staticfiles&#039;,
    &#039;jwt_cookie.apps.JwtCookieConfig&#039;,
    &#039;rest_framework&#039;,
    &#039;corsheaders&#039;,
]
MIDDLEWARE = [
   ...
    &#039;corsheaders.middleware.CorsMiddleware&#039;,
...
]
CORS_ALLOW_CREDENTIALS = True

REST_FRAMEWORK = {
    &#039;DEFAULT_AUTHENTICATION_CLASSES&#039;: (
        &#039;jwt_cookie.authenticate.JwtInCookieAuthentication&#039;,
    ),
}
SIMPLE_JWT = {
    &#039;ACCESS_TOKEN_LIFETIME&#039;: timedelta(minutes=2),
    &#039;REFRESH_TOKEN_LIFETIME&#039;: timedelta(minutes=10),
    &#039;AUTH_COOKIE&#039;: &#039;access_token&#039;,  # Cookie name. Enables cookies if value is set.
    &#039;AUTH_COOKIE_DOMAIN&#039;: None,  # A string like &amp;quotexample.com&amp;quot, or None for standard domain cookie.
    &#039;AUTH_COOKIE_SECURE&#039;: False,  # Whether the auth cookies should be secure (https:// only).
    &#039;AUTH_COOKIE_HTTP_ONLY&#039;: True,  # Http only cookie flag.It&#039;s not fetch by javascript.
    &#039;AUTH_COOKIE_PATH&#039;: &#039;/&#039;,  # The path of the auth cookie.
    &#039;AUTH_COOKIE_SAMESITE&#039;: &#039;Lax&#039;,  # Whether to set the flag restricting cookie leaks on
    # cross-site requests. This can be &#039;Lax&#039;, &#039;Strict&#039;, or None to disable the flag.
}الآن اگه برنامه‌رو serve کنید احتمالا خطایی مبنی‌بر پیدا نشد JwtInCookieAuthentication میگیرید که مهم نیست چون در ادامه این کلاس رو اضافه می‌کنیم به برنامه. حالا طبق روال همیشه برای ساختن جداول ابتدایی برنامه جنگویی نیازه که مایگریت انجام بدیم و دستور زیر رو وارد می‌کنیم و یک کابر مدیر میسازیم:python manage.py migrate
python manage.py createsuperuserحالا که همه‌چیز آمادهٔ توسعه شده میریم تا apiview مورد نظرمون رو بنویسیم و کم‌کم به برنامه شکل بدیم. برای این کار فایل views.py توی اپ jwt_cookie رو به‌صورت زیر ویرایش می‌کنیم:from rest_framework_simplejwt.tokens import RefreshToken
from django.middleware import csrf
from rest_framework.views import APIView
from rest_framework.response import Response
from django.contrib.auth import authenticate
from django.conf import settings
from rest_framework import status

def get_tokens_for_user(user):
    refresh = RefreshToken.for_user(user)
    return {
        &#039;refresh&#039;: str(refresh),
        &#039;access&#039;: str(refresh.access_token),
    }


class LoginView(APIView):
    def post(self, request, format=None):
        data = request.data
        response = Response()
        username = data.get(&#039;username&#039;, None)
        password = data.get(&#039;password&#039;, None)
        user = authenticate(username=username, password=password)
        if user is not None:
            if user.is_active:
                data = get_tokens_for_user(user)
                response.set_cookie(
                    key=settings.SIMPLE_JWT[&#039;AUTH_COOKIE&#039;],
                    value=data[&amp;quotaccess&amp;quot],
                    expires=settings.SIMPLE_JWT[&#039;ACCESS_TOKEN_LIFETIME&#039;],
                    secure=settings.SIMPLE_JWT[&#039;AUTH_COOKIE_SECURE&#039;],
                    httponly=settings.SIMPLE_JWT[&#039;AUTH_COOKIE_HTTP_ONLY&#039;],
                    samesite=settings.SIMPLE_JWT[&#039;AUTH_COOKIE_SAMESITE&#039;]
                )
                csrf.get_token(request)
                response.data = {&amp;quotSuccess&amp;quot: &amp;quotLogin successfully&amp;quot, &amp;quotdata&amp;quot: data}
                return response
            else:
                return Response({&amp;quotNo active&amp;quot: &amp;quotThis account is not active!!&amp;quot}, status=status.HTTP_404_NOT_FOUND)
        else:
            return Response({&amp;quotInvalid&amp;quot: &amp;quotInvalid username or password!!&amp;quot}, status=status.HTTP_404_NOT_FOUND)خب همونطور که توی کد بالا میبینین ما یه کلاس LoginView داریم که براش یه متد post نوشتیم، توی این متد اول از داخل request نام کاربری و رمزعبوری که کاربر برامون ارسال کرده رو میگیریم و بعد میریم سراغ authenticate کردنش که این کلاس رو در ادامه می‌سازیم، اگه user = None باشه یعنی کاربری با مشخصات وارد شده پیدا نشده، اما اگه پیدا شه باید شرط بعدی رو بررسی کنیم که اصلا این کاربر active هست یا نه، دقت کنید بسته به مدل CustomUser شما ممکنه نیاز داشته باشین موارد دیگه‌ای رو هم بررسی کنین، من ساده‌ترین حالت ممکن رو براش در نظر گرفتم، ممکنه شما مثلا یه سری permission رو هم بخواین بررسی کنین که میتونین همینجا اضافه کنین. اینجا ما وقتی مطمئن شدیم که کاربر اجازه login داره متد get_tokes_for_user رو صدا می‌زنیم که میره به کمک RefreshToken از کتابخانه simplejwt توکن‌های لازم رو برای این کاربر پیدا میکنه. حالا کافیه توی response کاربر کوکی رو مطابق با کد بالا ست کنیم تا موارد خواسته شده براش قابل دسترسی باشه، حالا بریم سراغ فایل بعدی به اسم authenticate.py که کنار همون فایل views.py می‌سازیمش و محتواش رو مثل زیر تنظیم می‌کنیم:from rest_framework_simplejwt.authentication import JWTAuthentication
from django.conf import settings

from rest_framework.authentication import CSRFCheck
from rest_framework import exceptions


def enforce_csrf(request):
    check = CSRFCheck()
    check.process_request(request)
    reason = check.process_view(request, None, (), {})
    if reason:
        raise exceptions.PermissionDenied(&#039;CSRF Failed: %s&#039; % reason)


class JwtInCookieAuthentication(JWTAuthentication):
    def authenticate(self, request):
        header = self.get_header(request)

        if header is None:
            access_token = request.COOKIES.get(settings.SIMPLE_JWT[&#039;AUTH_COOKIE&#039;]) or None
        else:
            access_token = self.get_raw_token(header)
        if access_token is None:
            return None

        validated_token = self.get_validated_token(access_token)
        enforce_csrf(request)
        return self.get_user(validated_token), validated_tokenما نیاز داریم یک کلاس JwtInCookieAuthentication که از کلاس JWTAuthentication  ارث برده بسازیم و توش متد authenticate رو بازنویسی کنیم. همچنین دقت کنید که برای بهبود امنیت از enforce_csrf هم استفاده کنیم تا validation اون فرم رو درنظر گرفته باشیم. خب بخش اصلی کار انجام شده حالا کافیه آدرس api مورد نظر رو به برنامه اضافه کنیم و بریم سراغ تست کردنش، برای این‌کار اول توی urls.py اصلی توی شاخه proj این موارد رو اضافه می‌کنیم:from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path(&#039;admin/&#039;, admin.site.urls),
    path(&#039;user/&#039;, include(&#039;jwt_cookie.urls&#039;)),
]حالا توی مسیر jwt_cookie یه فایل urls.py می‌سازیم و موارد زیر رو بهش اضافه می‌کنیم (دقت کنید این‌ نام‌گذاری‌ها دلخواهه):from django.urls import path
from .views import LoginView

app_name = &amp;quotjwt_cookie&amp;quot

urlpatterns = [
    path(&#039;jwt/&#039;, LoginView.as_view(), name=&amp;quotlogin&amp;quot),
]حالا میتونیم با postman یا insomnia یه request به برنامه بزنیم و نتیجه رو ببینیم، قبل از همه python manage.py runserver رو فراموش نکنید.نمونه درخواست:و نمونه خروجی:اگر قسمت cookie رو هم بررسی کنید چیزی شبیه به این تصویر میبینید:امیدوارم به‌کارتون اومده باشه، مقاله اصلی رو از اینجا میتونین ببینین.</description>
                <category>امیرحسین</category>
                <author>امیرحسین</author>
                <pubDate>Thu, 27 Jan 2022 22:33:15 +0330</pubDate>
            </item>
                    <item>
                <title>به بهانهٔ روز برنامه‌نویس</title>
                <link>https://virgool.io/@geek/%D8%A8%D9%87-%D8%A8%D9%87%D8%A7%D9%86%D9%87%D9%94-%D8%B1%D9%88%D8%B2-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87%D9%86%D9%88%DB%8C%D8%B3-rlobphlfevs8</link>
                <description>امروز روز جهانی برنامه‌نویسه، من هم این روز رو اول به همهٔ برنامه‌نویس‌های واقعی و بعد به کدنویس‌های برنامه‌نویس پندار و در آخر به خودم که عضو خیلی کوچکی از این جامعهٔ همیشه درحال حل مسئله هستم تبریک می‌گم. برخلاف خیلی از پست‌های وبلاگی و شبکه‌های اجتماعی من نمی‌خوام علت نام‌گذاری این روز رو شرح بدم که خیلی راحت میشه با گوگل کردن دلیل انتخاب امروز به‌عنوان روز برنامه‌نویس رو فهمید، من می‌خوام به بهونهٔ این روز یه‌کم در مورد برنامه‌نویسی و حال و هواش براتون صحبت کنم، اغلب از پست‌های عمومی و شبکه‌های اجتماعی ممکنه خونده باشین که یک برنامه‌نویس شخصی اخمو، بشدت ضدحال، خیره به مانیتور، ضداجتماع، بداخلاق، تنها (Single)، ضدزن و ... شناخته میشه اما آیا همهٔ این صفات بد توی یک برنامه‌نویس گنجونده شده؟ اگه واقعا این‌طوره پس چرا برای پیشرفت جامعه و تسهیل زندگی بشر این همه برنامه‌نویس شبانه‌روز زحمت میکشن و اغلب محصولات معقولی به جامعه ارائه میدن که هدف اصلیش بهبود زندگی آدم‌هاست؟خب بیایم از نگاه یه برنامه‌نویس صفات بالارو درک کنیم، آره ممکنه خیلی وقت‌ها روی چهرهٔ ما اخم باشه چون بیشتر مواقع زندگیمون داریم برای پیدا کردن راه حل یک مسئله تلاش می‌کنیم اون‌هم نه با صدا و بلند بلند حرف زدن، بلکه دقیقا توی فکرمون غوغا میشه و این به‌صورت ناخودآگاه باعث چین خوردن پیشونی و بستن اخم‌ها میشه پس دلیل نمیشه آدم عصبانی و اخمویی باشیم!بهمون میگن ضدحال چون بیشتر کار میکنیم (چه ذهنی چه فیزیکی) تا تفریح، مواقعی که دوستای عادیمون دارن برنامه برای شمال رفتن می‌چینن ما داریم روی رفع یک باگ برای وبسایت فروشگاهی که اول هفته منتشرش کردیم کار می‌کنیم و طبیعیه که توی زمان مورد نظر اون جمع نتونیم همراهیشون کنیم!خیره به مانیتور بودن که اقتضای شغلمونه به‌هرحال مثلا یه نجار همیشه با چوب سر و کار داره، یه راننده همیشه به جاده خیره‌ست، پس ماهم نمیتونیم به مانیتور نگاه نکنیم!ضداجتماع!!!! واقعا؟؟؟؟ خیلی دوست دارم بدونم بجز حوزهٔ کاری برنامه‌نویسی و محیط زیست دقیقا چه اجتماع‌های مفیدی توی ایران وجود داره؟ (با کمی اغراق) پس ما واقعا ضداجتماع نیستیم بلکه بیشتر اجتماع ما توی فضای مجازی و تالارهای پرسش و پاسخ خلاصه میشه که باز هم برای یادگیری و رفع مشکلات نرم‌افزاریه! خب قبول دارم کمی اجتماع گریز باشیم چون کمتر با دیگران در حال معاشرتیم و رفیق صمیمی ما دستگاه دیجیتالیه که باهاش کار می‌کنیم و از طریقش زندگیمون میگذره!اینکه معمولا تنهاییم و با کسی توی رابطهٔ جدی نیستیم به خدا تقصیر ما نیست، سلیقهٔ دخترا یه‌کم به ما نمیخوره، یعنی معمولا دنبال پسرهایی هستن که شاید وقت آزاد زیاد دارن و موقعی که میخوان حرف بزنن همیشه حواس پسر بهشون جمع باشه، درحالیکه ما هم همینیم باور کنید اگر زمان مناسب کنار ما بشینن و بخوان برامون صحبت کنن ما هم به حرفشون توجه می‌کنیم و حواسمون بهشون هست، فقط باید زمان مناسب رو پیدا کنن نه زمانی که داریم یک الگوریتم پیاده می‌کنیم یا زمانی که به راه‌حل منطقی برای رفع فلان خطا فکر می‌کنیم! پس میشه گفت ۵۰درصد دلیل تنها بودن بیشتر ماها خود دخترا/پسرای عزیز هستن که برنامه‌نویسی و دنیاش رو درک نمیکنن :)بهمون میگن ضدزن!!! شما بیشترین جایی که مقام زن رو در کنار مرد میبینید توی نرم‌افزارها و سایت‌هاییه که برنامه‌نویس‌ها پیاده‌ش می‌کنن و مثلا موقع ثبت‌نام باید جنسیتتون رو مشخص کنید! اتفاقا برنامه‌نویس فارغ از جنسیت خودش به‌شدت به یک همدم که درکش کنه (مثل سایر آدم‌ها) نیاز داره، من خودم دوستان برنامه‌نویس زیادی دارم که همسرشون (چه مرد چه زن) رابطه‌ٔ خوبی باهاشون دارن و از توانایی و قدرت حل مشکلات زندگیشون راضین!روی هم رفته خواستم بگم یک برنامه‌نویس نه‌تنها ضداجتماع نیست بلکه برای بهبود جامعه و پیشرفت زندگی داره تلاش می‌کنه فقط نوع شغلش ایجاب می‌کنه شب و روز نداشته باشه، سیکل کاری منظم نداشته باشه، قطعا همسری که ساعت کاریش مشخص باشه و درآمدش معلوم خیلی برای اکثر جامعه قابل درکه اما برنامه‌نویس‌ها لزوما جایی استخدام نیستن و شغلی ندارن که ثابت باشه و مشخص تا بتونن روزانه از ساعت فلان تا فلان رو در خدمت خانواده باشن اما حتما میتونن به اندازهٔ فلان ساعت وقت برای همسر و فرزندانشون آزاد کنن و به امور زندگی بپردازن، فراموش نکنیم اگر فضای مجازی انقدر پیشرفت کرده و برای عموم جامعه مایهٔ سرگرمی شده بخش عظیمی‌ش بخاطر وجود برنامه‌نویس‌ها و مشاغل مشابهه، پس کسانی که اجتماع و مردم رو به هم مرتبط و نزدیک می‌کنن نمیتونن ضداجتماع باشن، شاید فقط کمی درون‌گرا باشن :)درضمن، برنامه‌نویس لزوما یک مرد نیست، توی سال‌های اخیر دخترهای زیادی به جمع برنامه‌نویس‌ها پیوستن و اتفاقا توی کارشون هم خیلی موفقن بخاطر همین هم که شده دیگه صفت تک‌کاربرهٔ ضدزن رو بهمون نگین:(امیدوارم از خوندن این متن خسته نشده باشین و کمی با دنیای جدید و متفاوت برنامه‌نویس‌ها (جدید از نظر قدمت شغلی نسبت به سایر مشاغل) آشنا شده باشین، امیدوارم روزی برسه که کشور ماهم #روزـبرنامه‌نویس رو به رسمیت بشناسه و برای تشویق افراد شاغل توی این زمینه شرکت‌ها حتا یک تبریک ساده رو در نظر بگیرن!موفق باشید</description>
                <category>امیرحسین</category>
                <author>امیرحسین</author>
                <pubDate>Fri, 13 Sep 2019 13:08:56 +0430</pubDate>
            </item>
                    <item>
                <title>تیرماه سیزده شو / تیرما سیزه شو</title>
                <link>https://virgool.io/@geek/%D8%AA%DB%8C%D8%B1%D9%85%D8%A7%D9%87-%D8%B3%DB%8C%D8%B2%D8%AF%D9%87-%D8%B4%D9%88-%D8%AA%DB%8C%D8%B1%D9%85%D8%A7-%D8%B3%DB%8C%D8%B2%D9%87-%D8%B4%D9%88-bkf5mvuaofqe</link>
                <description>تیرماه سیزده شو / تیرما سیزه شو یکی از جشن‌های باستانی شمال ایران یا دقیق‌تر بگم مازندرانه که به تیرگان هم معروفه، در تاریخ روایت شده که ایران برای مشخص کردن مرزش با توران از آرش کمانگیر (تیراندازی از طبرستان) خواسته تا تیری پرتاب کنه و این اتفاق در ۱۳ تیره ماه تاریخ طبری برابر با ۱۲ آبان خورشیدی میشده و مردم مازندران در این شب برنامه‌های دلنشینی برای شادی و جشن برگزار می‌کردن. اما متاسفانه با گذشت زمان این برنامه‌ها کمتر و کمتر شده تا اینکه امروز فقط به بحث خوردنی‌ها و نهایت گردوبازی ختم میشه. دیشب ما هم این مراسم باستانی رو پاس داشتیم و با فامیل مشغول گردوبازی شدیم جای همه‌تون خالی، از خوردنی‌ها هم بخوام بگم میوه‌های این فصل مثل پرتقال، نارنگی، خرمالو و ... که همیشه باید سر سفره تیرما سیزه شو حاضر باشن و البته انار (اگه دون شده باشه خیلی بیشتر میچسبه:))) ) نمیدونم این مراسم در سال‌های آینده چقدر ممکنه تغییر کنه همون‌طور که جشنی که پدران ما میگرفتن با جشنی که ما میگیریم خیلی فرق میکنه اما بنظرم مهم پاسداری ازین جشنه و اینکه بدونیم آرش کمانگیر کی بود و چه‌کار کرد، تاریخ رو مطالعه کنیم و از گذشته درس بگیریم.قطعا اگه توی اینترنت جست‌وجو کنید مطالب بیشتری در مورد این مراسم پیدا می‌کنین من فقط روایت چیزی رو کردم که سینه‌به‌سینه نقل شده و به من رسیده، درضمن اگه تونستین گردوبازی (اغوزکا) مازندرانی‌هارو یاد بگیرین بازی سرگرم کننده و جالبیه :)  یک نکته در مورد آرش کمانگیر هم بگم که در روایت اومده آرش از شهر آمل بوده اما الآن ساری تندیسش رو ساخته و نصب کرده که همون عکس بالا میشه، خب این رو هم میذاریم عدم میهن‌پرستی مسئولین شهر آمل که برای اساطیر و تاریخ خودش کاری نمیکنه :|</description>
                <category>امیرحسین</category>
                <author>امیرحسین</author>
                <pubDate>Sun, 04 Nov 2018 11:12:24 +0330</pubDate>
            </item>
                    <item>
                <title>مردی به‌نام اُوه، کوتاه و دوست‌داشتنی</title>
                <link>https://virgool.io/@geek/%D9%85%D8%B1%D8%AF%DB%8C-%D8%A8%D9%87%D9%86%D8%A7%D9%85-%D8%A7%D9%8F%D9%88%D9%87-%DA%A9%D9%88%D8%AA%D8%A7%D9%87-%D9%88-%D8%AF%D9%88%D8%B3%D8%AA%D8%AF%D8%A7%D8%B4%D8%AA%D9%86%DB%8C-h5rsei7cjcfc</link>
                <description>قصه از جایی شروع میشه که درواقع نزدیک به پایانه، این کتاب نه‌چندان قطور با متنی بسیار ساده و ترکیبی از غم و طنز انقدر من رو به خودش جذب کرد که شاید نتیجه قبولی کنکور نتونست توجه من رو به خودش جلب کنه :)رمان سوئدی مردی به‌نام اُوه داستان پیرمردی ۵۹ساله رو بازگو می‌کنه که شامل دوران کودکی، جوانی و پیری این شخص میشه، اُوه پیرمردی ناخوشحاله (عجب واژه‌ای) که دوست داره تمام کارهارو مطابق با یک قانون و نظم خاصی پیش ببره، مردی که در هرچقدر تلاش میکنه تا خودش رو غیرمنعطف و نامهربون نشون بد در عین‌حال بیشترین کمک‌هارو به آشنایان و همسایه‌هاش میرسونه، مردی که مصداق بارز مردهای دهه‌ی ۳۰ و ۴۰ ایران میشه چون از کارهای فنی سر درمیاره، برای کوچکترین تعمیری سراغ تعمیرکار نمیره و از تمام وجودش حس مسؤولیت‌پذیری میباره، در طول داستان از مدرسه فرار میکنه، شاغل میشه، تنبیه و اخراج میشه، عاشق میشه و حتی تا مرز پدر شدن پیش میره ولی خُب نویسنده جور دیگه‌ای داستان رو تمام میکنه.هرچند من چاپ نهم این کتاب رو خوندم اما خوندنش رو به کسانی که علاقه به داستان‌های لطیف دارن و اهل رمان‌های چندجلدی نیستن به‌شدت پیشنهاد میدم، تا قبل ازینکه دیگه توی بازار کتاب پیدا نشه:)</description>
                <category>امیرحسین</category>
                <author>امیرحسین</author>
                <pubDate>Mon, 22 Oct 2018 12:32:04 +0330</pubDate>
            </item>
            </channel>
</rss>