<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های Hossein Safari</title>
        <link>https://virgool.io/feed/@hossein.sch75</link>
        <description>یه برنامه نویسی که کُشتی گیره (:</description>
        <language>fa</language>
        <pubDate>2026-06-10 21:25:26</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/37212/avatar/JyELrY.png?height=120&amp;width=120</url>
            <title>Hossein Safari</title>
            <link>https://virgool.io/@hossein.sch75</link>
        </image>

                    <item>
                <title>Authentication &amp; Authorize in Ruby on Rails (part 2 --&gt; with JWT)</title>
                <link>https://virgool.io/@hossein.sch75/authentication-authorize-in-ruby-on-rails-part-1-with-jwt-dhwnuc6kofoj</link>
                <description>سلام، در این مقاله میخوایم راجع به Authentication و authorize با JWT صحبت کنیم. در واقع این قسمت دوم از Authentication &amp; Authorize in Ruby on Rails هست. پس حتما قسمت اول رو بخونین و بعد بیاین سراغ قسمت دوم.همچنین شما میتونین از طریق گیت هابم یعنی از اینجا به این پروژه دسترسی داشته باشید.من همچنان ترجیح میدم در کنار این پروژه هم، چای لاهیجان بنوشم و لذت ببرم (:برای شروع درون فایل Gemfile رفته و &#x27;gem &#x27;jwt رو در این فایل اضافه کنین.خب دستور bundle install رو بزنین که gem های جدید نصب بشن.ممنون!در ابتدا چند متد رو خدمتتون توضیح میدم، سپس این توابع رو در پروژه به کار میبریم.def encode_token(payload)
    JWT.encode(payload, &#039;s3cr3t&#039;)
endمتد encode جزئی از JWT است و ما به وسیله encode، یک token میسازیم. این متد دو آرگومان میگیره. اولین آرگومان یه hash هستش و دومی یه secret هست. دقت کنین از secretی که در encode استفاده میکنیم، در decode هم باید از همین secret استفاده کنیم.def decode_token
  if auth_header
    token = auth_header.split(&#039; &#039;)[1]
    begin
      JWT.decode(token, &#039;s3cr3t&#039;, true, algorithm: &#039;HS256&#039;)
    rescue JWT.DecodeError
      nil
    end
  end
endمتد decode هم جزئی از JWT هست و ما به وسیله ی متد decode، اطلاعاتی از token بیرون می اوریم. در واقع این اطلاعات، همان objectی است که به متد encode دادیم تا tokenی برای ما بسازد.این متد چهار آرگومان میگیرد. اولی tokenی که ساخته بودیم است، دومی secretی است که هنگام encode داده بودیم، سومی یک مقدار true است و در نهایت الگوریتمی که میخوایم باهاش decode انجام بشه.def auth_header
  # { Authorization: &#039;Bearer &lt;token&gt;&#039; }
  request.headers[&#039;Authorization&#039;]
endوقتی ما sign-up یا log-in انجام میدیم، یه tokenی میگیریم. این token رو باید در هر requestی بفرستیم تا system تشخیص بده که ما log-in کردیم یا نه.از متد auth_header استفاده میکنیم تا token فرستاده شده رو به دست بیاریم.برای اینکه token رو درset ،postman کنیم، باید در قسمت Authorization، تایپش رو به &lt;Bearer &lt;token تغییر بدیم و همچنین tokenی که داریم رو  در قسمت token پیست میکنیم.همونطور که در قسمت اول خدمتتون عرض کردم، همه ی کنترولر ها از ‌ApplicationController ارث میبرند، ما این سه تابعی که در بالا توضیح دادم رو در همین کنترولر قرار میدیم.class ApplicationController &lt; ActionController::API
  before_action :authorize

  protected

  def authorize
    render json: { message: [&#039;Please log in&#039;] }, status: 401 unless User.find(session[:user_id])
    if decode_token
      user_id = decode_token[0][&#039;user_id&#039;]
      render json: { message: [&#039;Please log in&#039;] }, status: 401 unless User.find(user_id)
    else
      render json: { message: [&#039;Please log in&#039;] }, status: 401
    end
  end

  def encode_token(payload)
    JWT.encode(payload, &#039;s3cr3t&#039;)
  end

  def decode_token
    if auth_header
      token = auth_header.split(&#039; &#039;)[1]
      begin
        JWT.decode(token, &#039;s3cr3t&#039;, true, algorithm: &#039;HS256&#039;)
      rescue JWT.DecodeError
        nil
      end
    end
  end

  def auth_header
    # { Authorization: &#039;Bearer &lt;token&gt;&#039; }
    request.headers[&#039;Authorization&#039;]
  end
end در قسمت authorize علاوه بر اینکه از طریق session به ID کاربر یا user دسترسی پیدا می کنیم، از طریق encode کردن token به ID مورد نظر نیز دسترسی پیدا میکنیم.در کنترولر session هم از این متد ها به صورت زیر استفاده میکنیم.class SessionsController &lt; ApplicationController
  skip_before_action :authorize

  def create
    @user = User.find_by( email: params[:email] )
    if @user.try(:authenticate, params[:password])
      token = encode_token({ user_id: @user.id })
      render json: {user: @user, token: token}, status: 200
    else
      render json: { message: [&#039;Invalid user/password combination&#039;] }, status: 400
    end
  end

  def destroy
    session[:user_id] = nil
    render json: { message: [&#039;Logged out&#039;] }, status: 200
  end
endدر متد create، علاوه بر اینکه ID کاربر رو در session ذخیره می کنیم، از ID برای ساخت token هم استفاده میکنیم.</description>
                <category>Hossein Safari</category>
                <author>Hossein Safari</author>
                <pubDate>Sat, 29 Aug 2020 20:53:49 +0430</pubDate>
            </item>
                    <item>
                <title>Authentication &amp; Authorize in Ruby on Rails (part 1 --&gt; without JWT)</title>
                <link>https://virgool.io/coderlife/authentication-authorize-in-ruby-on-rails-grlp9mgothyo</link>
                <description>سلام، همونطور که اطلاع دارین(یعنی امیدوارم که اطلاع داشته باشین!)، میخوایم راجع به Authentication و Authorize در Ruby on Rails صحبت کنیم.قبل از اینکه شروع کنیم، خدمتتون عرض کنم که این مقاله رو در دو قسمت مینویسم.قسمت اول  راجع به Authentication و Authorize صحبت میکنیم.قسمت دوم راجع به این که چطوری JWT ایجاد کنیم و ازش استفاده کنیم، صحبت خواهیم کرد.در ابتدا میریم سراغ ساخت یه پروژه ی کوچیک در rails و سپس میریم سراغ Authentication و Authorize.راستی بیاین قبل از اینکه شروع کنیم، یه لیوان چای لاهیجان(یکی از شهرستان های استان گیلان معروف به عروس گیلان) آماده کنیم و همینطور که این پروژه رو میبریم جلو، چای هم نوش جان کنیم (:میتونین از طریق گیت هابم یعنی از اینجا به این پروژه دسترسی داشته باشید.خب یه پروژه به اسم authentication_authorize_project به صورت زیر میسازیم.rails new authentication_authorize_project --apiاگه میبینین از api-- استفاده کردیم، به این دلیل که نمیخوایم برامون view ایجاد بشه. (اگه هم نمیدونین چیه هم الان مهم نیست ولی بعدا حتما گوگل کنین).بعد از اینکه پروژه ساخته شد، با دستور cd authentication_authorize_project بِرید داخل پوشه ی پروژه و دستور bundle install رو بزنین.حالا برای اینکه مطمئن باشین که همه چی اوکیه، دستور rails s رو بزنین و در مرورگرتون آدرس http://127.0.0.1:3000 رو بزنین. اگه همه چی اوکی بوده باشه، باید صفحه ای زیبا که نوشته hey! You&#x27;re on Rails رو ببینین (:در این پروژه ما قصد داریم تا user رو authentication و authorize کنیم. برای این کار یک مدلِ User که فیلد های name, email, password داره رو به صورت زیر میسازیم.rails g model User name email password_digestفقط یه دستور کوچیک rails db:migrate هم بزنین که بریم سراغ مرحله ی اصلی.ما برای اینکه authentication و authorize انجام بدیم، از &#x27;gem &#x27;bcrypt استفاده میکنیم. برای اینکار باید بریم درون فایل Gemfile.rb در پروژه و &#x27;gem &#x27;bcrypt رو که در این فایل کامنت هست رو از حالت کامنت بیرون بیاریم. حالا دومرتبه دستور bundle install رو میزنیم تا gem مورد نظر ما نصب بشه.درون مدل User، متد has_secure_password رو اضافه میکنیم که تا مطمئن باشیم password به صورت encrypted درون دیتابیس ذخیره بشه. ناگفته نماند که این متد جزئی از bcrypt است.همچنین متد has_secure_password، علاوه بر کاری که در بالا خدمتتون عرض کردم، password و password_confirmation رو هم مقایسه میکنه که با هم match باشند. منتها یه مشکلی که در اینجا وجود داره، اگه nil ،password_confirmation باشه، باز هم رکورد ما در دیتابیس ذخیره میشه. برای جلوگیری از این کار، یه validates به مدل User به صورت زیر اضافه میکنیم.validates :password_confirmation, presence: trueحالا باید یه کنترولر برای user بسازید. برای اینکار از دستور زیر اسفاده کنین.rails g controller usersفایل routes.rb رو باز کنین و resource کنترولر جدید رو به صورت زیر درونش اضافه کنین.Rails.application.routes.draw do
    resources :users
endالان بِرید داخل کنترولرِ user و یک action به اسم create ایجاد کنید. حالا میتونین مثل قطعه کد پایین، sign up کنین و user جدید رو در دیتابیس ذخیره کنین (:class UsersController &lt; ApplicationController
  before_action :user_params

  def create
    @user = User.new(user_params)
    if @user.save
      render json: { message: [&#039;Saved&#039;] }, status: 200
    else
      render json: { message: [&#039;Not Saved&#039;] }, status: 400
    end
  end

  private

  def user_params
    params.permit(:name, :email, :password, :password_confirmation)
  end
endمن برای request زدن از postman استفاده میکنم، شما میتونین از هرچی دلتون میخواد استفاده کنین.راستی، چون ما موقع ایجاد مدل User برای password از password_digest استفاده کردیم، تنها یه فیلد password که encrypted هم هست در دیتابیس ذخیره میشه.Authentication:در ابتدا یه کنترولر به اسم Sessions با اکشن های create و destroy به صورت زیر ایجاد میکنیم.rails g controller Sessions create destroyبه کد زیر با دقت نگاه کنین. در واقع ما یه سرچ زدیم تا user مورد نظرمون رو از طریق اسمی که از پارامتر بهمون میرسه، پیدا کنیم. چون ما از bcrypt استفاده کردیم، یه متدی به نام authenticate بهمون میده و کارش اینه، passwordی که بهش میدیم  رو با passwordی که در دیتابیس ذخیره شده بود رو با هم مقایسه میکنه و true یا false بر میگردونه. اگه true بر گردونه، ما ID یوزر مورد نظر رو در session ذخیره میکنیم.در قسمت destroy هم session یوزری که وجود داره رو nil میکنه.class SessionsController &lt; ApplicationController
  def create
    user = User.find_by( email: params[:email] )
    if user.try(:authenticate, params[:password])
      session[:user_id] = user.id
      render json: { message: [&#039;Welcome&#039;] }, status: 200
    else
      render json: { message: [&#039;Invalid user/password combination&#039;] }, status: 400
    end
  end

  def destroy
    session[:user_id] = nil
    render json: { message: [&#039;Logged out&#039;] }, status: 200
  end
endبریم  routes های کنترولر session هم set کنیم تا بتونیم login و logout انجام بدیم.controller :sessions do
  post &#039;login&#039; =&gt; :create
  delete &#039;logout&#039; =&gt; :destroy
endAuthorize:ما در اینجا بررسی میکنیم که دسترسی یک کاربر یا یوزر به کنترولر های مختلف سایت ما چطور هست.چون تمام کنترولر های ما از ApplicationController ارث میبرند، لذا ما متد  authorize رو در ApplicationController ایجاد میکنیم.class ApplicationController &lt; ActionController::API
  before_action :authorize

  protected

  def authorize
    unless User.find_by(id: session[:user_id])
      render json: { message: [&#039;Please log in&#039;] }, status: 401
    end
  end
endمتد authorize قبل از شروع همه ی کنترولر ها اجرا میشه. حتی زمانی هم که login می کنیم، دومرتبه به ما ارور میده که please login. برای حل این مشکل دستور زیر رو، در کنترولر هایی که نمیخوایم قبل از شروعشون، متد authorize اجرا بشه، مینویسیم.skip_before_action :authorizeاگه سوالی هست خوش حال میشم بتونم کمکتون کنم (:امیدوارم از چایتون لذت برده باشید ((:</description>
                <category>Hossein Safari</category>
                <author>Hossein Safari</author>
                <pubDate>Fri, 28 Aug 2020 16:59:49 +0430</pubDate>
            </item>
                    <item>
                <title>اضافه کردن فونت دلخواه در ریاکت</title>
                <link>https://virgool.io/@hossein.sch75/%D8%A7%D8%B6%D8%A7%D9%81%D9%87-%DA%A9%D8%B1%D8%AF%D9%86-%D9%81%D9%88%D9%86%D8%AA-%D8%AF%D9%84%D8%AE%D9%88%D8%A7%D9%87-%D8%AF%D8%B1-%D8%B1%DB%8C%D8%A7%DA%A9%D8%AA-aoj5t14r9why</link>
                <description>برای اینکه یه فونت دلخواهی مثل B-Nazanin رو در پروژه ی ریاکتی خود اضافه کنید، کافیه فقط یه لیوان چای نوش جان کنین! و چند مرحله زیر رو انجام بدید ((:۱ـ اول باید فونت دلخواه خودتون رو دانلود کنین، پس اول برید گوگل کنین و فونت دلخواه خودتون رو که با فرمت ttf. هستش رو دانلود کنین.۲ـ یه فولدر یا دایرکتوری به اسم fonts در روت اصلی یا srcیِ پروژتون ایجاد کنین..src/fonts۳ـ حالا فونتی که دانلود کردین(با فرمت ttf.) رو درون پوشه ی fonts کپی کنین.۴ـ درون index.js پروژتون فونتی که دانلود کردین رو import کنین.import &#039;./fonts/B-Nazanin.ttf&#039;۵ـ حالا باید font-face رو در index.css اضافه کنین.@font-face {
  font-family: &#039;B-Nazanin&#039;;
  src: local(&#039;B-Nazanin&#039;), url(./fonts/B-Nazanin.ttf) format(&#039;truetype&#039;);
}۶ـ خب حالا دیگه میتونین از فونت مورد نظرتون استفاده کنین، کافیه از دستور font-family استفاده کنین..body {
  font-family: B-Nazanin
}امیدوارم چاییتون سرد نشده باشه (:</description>
                <category>Hossein Safari</category>
                <author>Hossein Safari</author>
                <pubDate>Tue, 14 Jan 2020 20:19:39 +0330</pubDate>
            </item>
                    <item>
                <title>نصب همزمان یک پکیج پایتون با ورژن های مختلف در پروژه های مختلف (با استفاده از virtualenv)</title>
                <link>https://virgool.io/@hossein.sch75/%D9%86%D8%B5%D8%A8-%D9%87%D9%85%D8%B2%D9%85%D8%A7%D9%86-%DB%8C%DA%A9-%D9%BE%DA%A9%DB%8C%D8%AC-%D9%BE%D8%A7%DB%8C%D8%AA%D9%88%D9%86-%D8%A8%D8%A7-%D9%88%D8%B1%DA%98%D9%86-%D9%87%D8%A7%DB%8C-%D9%85%D8%AE%D8%AA%D9%84%D9%81-%D8%A8%D8%A7-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-virtualenv-bpchcjgyv5em</link>
                <description>شده تا به حال روی پروژه ای مثل A دارین کار میکنین و میخواین به صورت موازی روی یه پروژه ی دیگه ای مثل B  کاری کنین، به طوریکه در هر دو پروژه بخواین از پکیج های مشترک ولی با ورژن های مختلف استفاده کنین؟شده تا به حال بخواین پکیجی رو در دایرکتوری دلخواه خودتون نصب کنین؟اگه همچین مشکلاتی داشتین و یا دارین با من همراه باشین (:برای اینکار از virtual environment استفاده میکنیم.حالا این Virtualenvی که میگیم چی هست؟!!یه ابزاری برای ساخت محیطی در پایتون هستش که پکیج هایی که به وسیله pip نصب میکنیم رو فقط در همون پروژه نگه داری میکنه. یعنی پکیج هایی که نصب میکنیم به صورت global نصب نمیشه.در واقع ما میتونیم از یه پکیجی مثل ansible با یه ورژنی در یه پروژه استفاده کنیم و به طور همزمان از پکیج ansible اما با ورژن دیگه ای در پروژه ی دیگه استفاده کنیم.نصب Virtualenv در اوبونتو:۱ـ کافیه کد دستوری زیر رو بزنیم تا Virtualenv برامون نصب بشه.pip3 install virtualenv۲ـ دستور زیر یه محیطی به اسم projectnv (هر اسمی که دلمون بخواد میتونیم بزاریم) میسازه.virtualenv projectnv۳ـ حالا باید این محیط رو فعالش کنیم، برای اینکار از دستور زیر استفاده میکنیم.source projectnv/bin/activate*با انجام دستور بالا در ابتدای خط فرمان لینوکس باید اسم محیطی که فعال کردیم رو ببینیم، شبیه تصویر پایین.۴ـ با زدن دستور زیر میتونیم مطمئن بشیم که آیا پایتون از همین محیطی که ساختیم داره استفاده میکنه یا نه.which python3*به تصویر زیر توجه کنید.۵ـ خب حالا دیگه میتونیم پکیجی که میخوایم رو در همین دایرکتوری یا محیطی که ساختیم نصب کنیم و ازش در پروژمون استفاده کنیم (:برای مثال پکیج requests رو نصب میکنیم: pip3 install requests*در نهایت اگه بخوایم ببینیم که واقعا پکیج requests در همین محیطی که ساختیم نصب شده یا نه، کافیه دستور زیر رو بزنیم.pip3 show requests**خروجی دستور بالا شبیه این تصویر هستش:</description>
                <category>Hossein Safari</category>
                <author>Hossein Safari</author>
                <pubDate>Fri, 03 Jan 2020 00:00:29 +0330</pubDate>
            </item>
                    <item>
                <title>چگونه از ES6 در NodeJS استفاده کنیم؟</title>
                <link>https://virgool.io/iran-nodejs-community/%DA%86%DA%AF%D9%88%D9%86%D9%87-%D8%A7%D8%B2-es6-%D8%AF%D8%B1-nodejs-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%DA%A9%D9%86%DB%8C%D9%85-lcwi8sciyhe4</link>
                <description>برای اینکه از ES6 در NodeJS استفاده کنیم، ما از Babel استفاده میکنیم.‌Babel چیست؟Babel یک کامپایلر جاوا اسکریپت است. به وسیله Babel ما میتونیم کد +ECMAScript 2015 را به نسخه های قبلی جاوا اسکریپت تبدیل کنیم.۱ـ برای این کار ابتدا باید NodeJS رو در سیستم خود نصب کنیم. اگر هنوز NodeJS رو نصب نکردین، کافیه اینجا کلیک کنین. البته این لینکی که گذاشتم برای لینوکسی ها هستش؛ اگه توی ویندوز هستین کافیه برین توی سایت NodeJS و دانلودش کنین. نصبش هم خیلی راحته، فقط چند تا next داره! ((:۲ـ بعد از نصب NodeJS، یک پروژه ی جدید میسازیم. mkdir new_project
cd new_project۳ـ درون مسیری که برای این پروژه خود ساختیم؛ دستور زیر رو مینویسیم تا package.json به پروژه ی ما اضافه بشه.npm init۴ـ حالا Babel را نصب میکنیم.npm install --save-dev @babel/core @babel/cli
npm install @babel/preset-env --save-dev۵ـ درون فایل  package.json میریم و قسمت scripts رو شبیه زیر تغییر میدیم.&amp;quotscripts&amp;quot: {
&amp;quottest&amp;quot: &amp;quotecho \&amp;quotError: no test specified\&amp;quot &amp;&amp; exit 1&amp;quot,
&amp;quotbuild&amp;quot: &amp;quotbabel src -d lib&amp;quot
}۶ـ درون پروژه خود یه پوشه ی src میسازیم و یه فایلی به هر نامی که دلمون میخواد درون پوشه ی src میسازیم. (من اسمش رو index.js گذاشتم)حالا یه سری کد ES6 توش مینویسیم. مثل:import request from &#039;requests&#039;;
let helloWorld = &#039;Hello World!`;
console.log(`${helloWorld} this is some ES6 JavaScript code`);۷ـ درون دایرکتوری اصلی پروژه، فایلی به نام babelrc. میسازیم.درون این فایل کد زیر رو مینویسیم:{   &amp;quotpresets&amp;quot: [&amp;quot@babel/preset-env&amp;quot] }۸ـ با زدن دستور زیر در دایرکتوری اصلی پروژه، به طور خودکار پوشه ای به نام lib ساخته میشود و درون این پوشه فایلی به نام index.js نیز ساخته میشود. درون این فایل هم، کد هایی که در مرحله ۶ نوشته بودیم کامپایلر شده و درون این فایل قرار میگیرد.npm run build* در واقع در این مرحله babel، کد +ECMAScript 2015 رو به نسخه های قبلی جاوا اسکریپت کامپایلر میکنه.</description>
                <category>Hossein Safari</category>
                <author>Hossein Safari</author>
                <pubDate>Thu, 12 Dec 2019 23:18:58 +0330</pubDate>
            </item>
            </channel>
</rss>