Skip to content

Archives

  • اکتبر 2021
  • فوریه 2021
  • سپتامبر 2020
  • آگوست 2020
  • جولای 2020
  • مارس 2020
  • ژانویه 2020

Categories

  • امنیت
  • برنامه نویسی
  • بهینه سازی کد
  • جاوااسکریپت
  • رمزنگاری
  • گنو/لینوکس

Copyright جعفر آخوندعلی 2022 | Theme by ThemeinProgress | Proudly powered by WordPress

  • English
  • فارسی
جعفر آخوندعلییه برنامه نویس دیگه

توکن رو کجا ذخیره کنیم؟ کوکی یا LocalStorage؟ چرا و چطور؟

امنیت . برنامه نویسی . جاوااسکریپتOn 2020-08-14 by Jafar
زمان مطالعه: 3 دقیقه

وقتی صحبت از احراز هویت توی صفحه های SPA میشه، خیلی وقتا این سوال مطرح میشه که برای اینکه بعد از بستن مرورگر نیاز به توکن احراز هویت رو کجا ذخیره کنیم؟ معمولا این ۲ گزینه ها جز مهم ترین انتخاب ها هستن:

  1. ذخیره کردن توی Local Storage یا محل های مشابه
  2. ذخیره کردن توی کوکی

چیزی توی اکثر پیاده سازی ها میبینم،‌استفاده از Local Storage هست. به اینصورت که توکن رو یا توی state ذخیره میکنن و کل state رو میزارن توی Local Storage و یا مستقیم خوده token رو توی Local Storage ذخیره میکنن. خب با این روش، صفحه داره کار میکنه، اما آیا این روش امن هست ؟

نه، این روش(نسبتاً) امن نیست! دلیلش اینه که اگر توی صفحه وب شما، باگ XSS وجود داشته باشه، مهاجم میتونه به راحتی مقادیر موجود در Local Storage شمارو بخونه و برای خودش ارسال کنه.

خب اگه بخوایم در برابر این حمله مقاوم باشیم، باید از یچیزی استفاده کنیم که Javascript نتونه بهش دسترسی داشته باشه !

جواب: استفاده از کوکی های HttpOnly

اگر از کوکی های معمولی استفاده کنیم، برای کارِ ما آنچنان فرقی با برای ما نداره چون توسط Javascript قابل دسترسی هست و برمیگردیم به پله اول. اما کوکی ها یه فلگ دارن به اسم HttpOnly که راه چاره ماست

فلگ HttpOnly توی کوکی چیه؟ 😐

این فلگ نشون دهنده اینه که کوکی فقط توی درخواست های (s)Http ارسال میشه و دیگه توسط Javascript قابل دیدن یا نوشته شدن نیست. یعنی در برابر حملات XSS مقاوم میشه.

اگه نمیشه با Javascript بهش دسترسی داشت چطوری ازش استفاده کنیم؟‌

برای اینکه بخواین یه کوکی رو توی مرورگر تنظیم کنیم ۲ تا راه هست:

  1. کوکی رو با جاوا اسکریپت توی مرورگر تنظیم کنیم
  2. کوکی رو از سمت سرور با هدر set-cookie تنظیم کنیم

کوکی هایی که از نوع HttpOnly باشن فقط و فقط از طریق سرور قابل خوندن و نوشتن هستن. پس کافیه کارِ احراز هویت رو به سرور بسپاریم.

برای مثال، من اینکار رو با express به اینصورت پیاده کردم:

const express = require('express');
const cookieParser = require('cookie-parser');

const app = express();
app.use(cookieParser());

// TODO: this should be generated and validated properly (via jwt for example)
const secretToken = "MY_SECRET_RANDOM_GENERATED_TOKEN";


/**
 * Login route - Currently no real authentication is involved, allow everyone to login
 */
app.get('/login', (req, res)=>{
  // TODO: Do some real authentication then set the httpOnly cookie
  const cookieName = 'access_token';
  const cookieValue = secretToken;
  const cookieOptions = { httpOnly: true, expires: new Date(Date.now() + 3600000 * 24 * 365 ) }
  return res
    .cookie(cookieName, cookieValue, cookieOptions)
    .status(201)
    .send('Done');
});

/**
 * This route checks whether we are authenticated or not
 */
app.get('/test', (req, res)=>{
  const isAuthenticated = req.cookies['access_token'] === secretToken;
  return res.send(`You are ${ isAuthenticated ? '' : 'not' } authenticated`);
});

const expressPort = 3085;
app.listen(expressPort, () => { console.log(`Running on ${expressPort}`) });

هر وقت به مسیر /login یه درخواست get بزنیم، کوکی برای ما تنظیم میشه (مهم نیست با ajax باشه یا نه). و برای چک کردنه اینکه کوکی سمت سرور قابل خوندن هست یا نه، کافیه به مسیر /test یه درخواست بزنیم.

خب الان من با مرورگرم به مسیر login رفتم و دیدم که کوکی با موفقیت برای من ست شده:

اما اگر از طریق console، بخوام کوکی هارو بخونم، هیچ مقداری قابل دیدن نیست:

برای تست نهایی، کافیه به مسیر test برم و مطمئن بشم که سرور میتونه کوکی رو بخونه:

و کار تمام شد. پس دیدیم که به سادگی میشه توکن رو توی کوکی ذخیره کرد، بدون اینکه Javascript بهش دسترسی داشته باشه.

همچنین برای تامین امنیت بیشتر توصیه میشه موارد زیر خونده بشه:

  • CSRF
  • Secure Cookie

21

مثل این مطلب:

رمزنگاری چیست، که بود و چه کرد؟
انواع رمزنگاری، تفاوت ها، مزایا و معایب
چطوری به ریش سامانه دانشگاهی سما بخندیم؟

پاسخ ها

احسان گازار 2020-09-09 at 02:40 - پاسخ

فقط یه برنامه نویس دیگه؟ 🙂
به نظر که یه برنامه‌نویس خوبه دیگه٬
ممنون بابت این مطلب

نظرت چیه؟ لغو پاسخ

نشانی ایمیل شما منتشر نخواهد شد.

این سایت توسط reCAPTCHA و گوگل محافظت می‌شود حریم خصوصی و شرایط استفاده از خدمات اعمال.

It’s Me

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

  • twitter
  • twitter
  • linkedin
  • github
  • telegram
  • telegram
Preloaded shit
  • فارسیفارسی
  • EnglishEnglish

دسته‌ها

  • امنیت (5)
    • رمزنگاری (3)
  • برنامه نویسی (8)
    • بهینه سازی کد (2)
    • جاوااسکریپت (2)
  • گنو/لینوکس (3)