<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>نوشته های Hossein Safari</title><link>https://virgool.ir/feed/@hossein.sch75</link><description>یه برنامه نویسی که کُشتی گیره (:</description><language>fa</language><pubDate>2026-11-11 07:11:46</pubDate><image><url>https://files.virgool.ir/upload/users/37212/avatar/JyELrY.png</url><title>Hossein Safari</title><link>https://virgool.ir/@hossein.sch75</link></image><item><title>Authentication &amp; Authorize in Ruby on Rails (part 2 --&gt; with JWT)</title><link>https://virgool.ir/@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 رفته و &#39;gem &#39;jwt رو در این فایل اضافه کنین.خب دستور bundle install رو بزنین که gem های جدید نصب بشن.ممنون!در ابتدا چند متد رو خدمتتون توضیح میدم، سپس این توابع رو در پروژه به کار میبریم.def encode_token(payload)&#xA;    JWT.encode(payload, &#39;s3cr3t&#39;)&#xA;endمتد encode جزئی از JWT است و ما به وسیله encode، یک token میسازیم. این متد دو آرگومان میگیره. اولین آرگومان یه hash هستش و دومی یه secret هست. دقت کنین از secretی که در encode استفاده میکنیم، در decode هم باید از همین secret استفاده کنیم.def decode_token&#xA;  if auth_header&#xA;    token = auth_header.split(&#39; &#39;)[1]&#xA;    begin&#xA;      JWT.decode(token, &#39;s3cr3t&#39;, true, algorithm: &#39;HS256&#39;)&#xA;    rescue JWT.DecodeError&#xA;      nil&#xA;    end&#xA;  end&#xA;endمتد decode هم جزئی از JWT هست و ما به وسیله ی متد decode، اطلاعاتی از token بیرون می اوریم. در واقع این اطلاعات، همان objectی است که به متد encode دادیم تا tokenی برای ما بسازد.این متد چهار آرگومان میگیرد. اولی tokenی که ساخته بودیم است، دومی secretی است که هنگام encode داده بودیم، سومی یک مقدار true است و در نهایت الگوریتمی که میخوایم باهاش decode انجام بشه.def auth_header&#xA;  # { Authorization: &#39;Bearer &lt;token&gt;&#39; }&#xA;  request.headers[&#39;Authorization&#39;]&#xA;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&#xA;  before_action :authorize&#xA;&#xA;  protected&#xA;&#xA;  def authorize&#xA;    render json: { message: [&#39;Please log in&#39;] }, status: 401 unless User.find(session[:user_id])&#xA;    if decode_token&#xA;      user_id = decode_token[0][&#39;user_id&#39;]&#xA;      render json: { message: [&#39;Please log in&#39;] }, status: 401 unless User.find(user_id)&#xA;    else&#xA;      render json: { message: [&#39;Please log in&#39;] }, status: 401&#xA;    end&#xA;  end&#xA;&#xA;  def encode_token(payload)&#xA;    JWT.encode(payload, &#39;s3cr3t&#39;)&#xA;  end&#xA;&#xA;  def decode_token&#xA;    if auth_header&#xA;      token = auth_header.split(&#39; &#39;)[1]&#xA;      begin&#xA;        JWT.decode(token, &#39;s3cr3t&#39;, true, algorithm: &#39;HS256&#39;)&#xA;      rescue JWT.DecodeError&#xA;        nil&#xA;      end&#xA;    end&#xA;  end&#xA;&#xA;  def auth_header&#xA;    # { Authorization: &#39;Bearer &lt;token&gt;&#39; }&#xA;    request.headers[&#39;Authorization&#39;]&#xA;  end&#xA;end در قسمت authorize علاوه بر اینکه از طریق session به ID کاربر یا user دسترسی پیدا می کنیم، از طریق encode کردن token به ID مورد نظر نیز دسترسی پیدا میکنیم.در کنترولر session هم از این متد ها به صورت زیر استفاده میکنیم.class SessionsController &lt; ApplicationController&#xA;  skip_before_action :authorize&#xA;&#xA;  def create&#xA;    @user = User.find_by( email: params[:email] )&#xA;    if @user.try(:authenticate, params[:password])&#xA;      token = encode_token({ user_id: @user.id })&#xA;      render json: {user: @user, token: token}, status: 200&#xA;    else&#xA;      render json: { message: [&#39;Invalid user/password combination&#39;] }, status: 400&#xA;    end&#xA;  end&#xA;&#xA;  def destroy&#xA;    session[:user_id] = nil&#xA;    render json: { message: [&#39;Logged out&#39;] }, status: 200&#xA;  end&#xA;endدر متد create، علاوه بر اینکه ID کاربر رو در session ذخیره می کنیم، از ID برای ساخت token هم استفاده میکنیم.</description><category>Hossein Safari</category><author>Hossein Safari</author><pubDate>Sat, 29 Aug 2020 21:53:49 +0430</pubDate></item><item><title>Authentication &amp; Authorize in Ruby on Rails (part 1 --&gt; without JWT)</title><link>https://virgool.ir/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&#39;re on Rails رو ببینین (:در این پروژه ما قصد داریم تا user رو authentication و authorize کنیم. برای این کار یک مدلِ User که فیلد های name, email, password داره رو به صورت زیر میسازیم.rails g model User name email password_digestفقط یه دستور کوچیک rails db:migrate هم بزنین که بریم سراغ مرحله ی اصلی.ما برای اینکه authentication و authorize انجام بدیم، از &#39;gem &#39;bcrypt استفاده میکنیم. برای اینکار باید بریم درون فایل Gemfile.rb در پروژه و &#39;gem &#39;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&#xA;    resources :users&#xA;endالان بِرید داخل کنترولرِ user و یک action به اسم create ایجاد کنید. حالا میتونین مثل قطعه کد پایین، sign up کنین و user جدید رو در دیتابیس ذخیره کنین (:class UsersController &lt; ApplicationController&#xA;  before_action :user_params&#xA;&#xA;  def create&#xA;    @user = User.new(user_params)&#xA;    if @user.save&#xA;      render json: { message: [&#39;Saved&#39;] }, status: 200&#xA;    else&#xA;      render json: { message: [&#39;Not Saved&#39;] }, status: 400&#xA;    end&#xA;  end&#xA;&#xA;  private&#xA;&#xA;  def user_params&#xA;    params.permit(:name, :email, :password, :password_confirmation)&#xA;  end&#xA;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&#xA;  def create&#xA;    user = User.find_by( email: params[:email] )&#xA;    if user.try(:authenticate, params[:password])&#xA;      session[:user_id] = user.id&#xA;      render json: { message: [&#39;Welcome&#39;] }, status: 200&#xA;    else&#xA;      render json: { message: [&#39;Invalid user/password combination&#39;] }, status: 400&#xA;    end&#xA;  end&#xA;&#xA;  def destroy&#xA;    session[:user_id] = nil&#xA;    render json: { message: [&#39;Logged out&#39;] }, status: 200&#xA;  end&#xA;endبریم  routes های کنترولر session هم set کنیم تا بتونیم login و logout انجام بدیم.controller :sessions do&#xA;  post &#39;login&#39; =&gt; :create&#xA;  delete &#39;logout&#39; =&gt; :destroy&#xA;endAuthorize:ما در اینجا بررسی میکنیم که دسترسی یک کاربر یا یوزر به کنترولر های مختلف سایت ما چطور هست.چون تمام کنترولر های ما از ApplicationController ارث میبرند، لذا ما متد  authorize رو در ApplicationController ایجاد میکنیم.class ApplicationController &lt; ActionController::API&#xA;  before_action :authorize&#xA;&#xA;  protected&#xA;&#xA;  def authorize&#xA;    unless User.find_by(id: session[:user_id])&#xA;      render json: { message: [&#39;Please log in&#39;] }, status: 401&#xA;    end&#xA;  end&#xA;endمتد authorize قبل از شروع همه ی کنترولر ها اجرا میشه. حتی زمانی هم که login می کنیم، دومرتبه به ما ارور میده که please login. برای حل این مشکل دستور زیر رو، در کنترولر هایی که نمیخوایم قبل از شروعشون، متد authorize اجرا بشه، مینویسیم.skip_before_action :authorizeاگه سوالی هست خوش حال میشم بتونم کمکتون کنم (:امیدوارم از چایتون لذت برده باشید ((:</description><category>Hossein Safari</category><author>Hossein Safari</author><pubDate>Fri, 28 Aug 2020 17:59:49 +0430</pubDate></item><item><title>اضافه کردن فونت دلخواه در ریاکت</title><link>https://virgool.ir/@hossein.sch75/اضافه-کردن-فونت-دلخواه-در-ریاکت-aoj5t14r9why</link><description>برای اینکه یه فونت دلخواهی مثل B-Nazanin رو در پروژه ی ریاکتی خود اضافه کنید، کافیه فقط یه لیوان چای نوش جان کنین! و چند مرحله زیر رو انجام بدید ((:۱ـ اول باید فونت دلخواه خودتون رو دانلود کنین، پس اول برید گوگل کنین و فونت دلخواه خودتون رو که با فرمت ttf. هستش رو دانلود کنین.۲ـ یه فولدر یا دایرکتوری به اسم fonts در روت اصلی یا srcیِ پروژتون ایجاد کنین..src/fonts۳ـ حالا فونتی که دانلود کردین(با فرمت ttf.) رو درون پوشه ی fonts کپی کنین.۴ـ درون index.js پروژتون فونتی که دانلود کردین رو import کنین.import &#39;./fonts/B-Nazanin.ttf&#39;۵ـ حالا باید font-face رو در index.css اضافه کنین.@font-face {&#xA;  font-family: &#39;B-Nazanin&#39;;&#xA;  src: local(&#39;B-Nazanin&#39;), url(./fonts/B-Nazanin.ttf) format(&#39;truetype&#39;);&#xA;}۶ـ خب حالا دیگه میتونین از فونت مورد نظرتون استفاده کنین، کافیه از دستور font-family استفاده کنین..body {&#xA;  font-family: B-Nazanin&#xA;}امیدوارم چاییتون سرد نشده باشه (:</description><category>Hossein Safari</category><author>Hossein Safari</author><pubDate>Tue, 14 Jan 2020 21:19:39 +0330</pubDate></item><item><title>نصب همزمان یک پکیج پایتون با ورژن های مختلف در پروژه های مختلف (با استفاده از virtualenv)</title><link>https://virgool.ir/@hossein.sch75/نصب-همزمان-یک-پکیج-پایتون-با-ورژن-های-مختلف-با-استفاده-از-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 01:00:29 +0330</pubDate></item><item><title>چگونه از ES6 در NodeJS استفاده کنیم؟</title><link>https://virgool.ir/iran-nodejs-community/چگونه-از-es6-در-nodejs-استفاده-کنیم-lcwi8sciyhe4</link><description>برای اینکه از ES6 در NodeJS استفاده کنیم، ما از Babel استفاده میکنیم.‌Babel چیست؟Babel یک کامپایلر جاوا اسکریپت است. به وسیله Babel ما میتونیم کد +ECMAScript 2015 را به نسخه های قبلی جاوا اسکریپت تبدیل کنیم.۱ـ برای این کار ابتدا باید NodeJS رو در سیستم خود نصب کنیم. اگر هنوز NodeJS رو نصب نکردین، کافیه اینجا کلیک کنین. البته این لینکی که گذاشتم برای لینوکسی ها هستش؛ اگه توی ویندوز هستین کافیه برین توی سایت NodeJS و دانلودش کنین. نصبش هم خیلی راحته، فقط چند تا next داره! ((:۲ـ بعد از نصب NodeJS، یک پروژه ی جدید میسازیم. mkdir new_project&#xA;cd new_project۳ـ درون مسیری که برای این پروژه خود ساختیم؛ دستور زیر رو مینویسیم تا package.json به پروژه ی ما اضافه بشه.npm init۴ـ حالا Babel را نصب میکنیم.npm install --save-dev @babel/core @babel/cli&#xA;npm install @babel/preset-env --save-dev۵ـ درون فایل  package.json میریم و قسمت scripts رو شبیه زیر تغییر میدیم.&#34;scripts&#34;: {&#xA;&#34;test&#34;: &#34;echo \&#34;Error: no test specified\&#34; &amp;&amp; exit 1&#34;,&#xA;&#34;build&#34;: &#34;babel src -d lib&#34;&#xA;}۶ـ درون پروژه خود یه پوشه ی src میسازیم و یه فایلی به هر نامی که دلمون میخواد درون پوشه ی src میسازیم. (من اسمش رو index.js گذاشتم)حالا یه سری کد ES6 توش مینویسیم. مثل:import request from &#39;requests&#39;;&#xA;let helloWorld = &#39;Hello World!`;&#xA;console.log(`${helloWorld} this is some ES6 JavaScript code`);۷ـ درون دایرکتوری اصلی پروژه، فایلی به نام babelrc. میسازیم.درون این فایل کد زیر رو مینویسیم:{   &#34;presets&#34;: [&#34;@babel/preset-env&#34;] }۸ـ با زدن دستور زیر در دایرکتوری اصلی پروژه، به طور خودکار پوشه ای به نام lib ساخته میشود و درون این پوشه فایلی به نام index.js نیز ساخته میشود. درون این فایل هم، کد هایی که در مرحله ۶ نوشته بودیم کامپایلر شده و درون این فایل قرار میگیرد.npm run build* در واقع در این مرحله babel، کد +ECMAScript 2015 رو به نسخه های قبلی جاوا اسکریپت کامپایلر میکنه.</description><category>Hossein Safari</category><author>Hossein Safari</author><pubDate>Fri, 13 Dec 2019 00:18:58 +0330</pubDate></item></channel></rss>