كيف اضع bearer token في Authorization في js fetch api

Zerious

جالس اتعلم استخدم laravel sanctum للتحقق و لكن اريد ان احصل bearer token الخاص بالمستخدم لارسال البيانات.

هل اعمل fetch api يأخذ bearer token الخاص بالمستخدم الذي يكون مخزن في session او هناك طريقة اخرى احصل عليه و اضعه في authorization header ؟

انا اريد استخدامه ليس في postman بل في موقع الكتروني عادي بستخدام fetch لان اذا استخدم auth:snctum يظهر لي unauthnticated لان bearer token ليس موجود في header كيف اجيب bearer token و اضعه header?

يرجى الدخول لحسابك أو تسجيل حساب لتستطيع إضافة تعليق
حساب جديد دخول

التعليقات

المتصفح لا يقوم تلقائياً بإرسال الـ Bearer Token مع طلبات fetch كما يفعل مع الـ Cookies. ولذلك ستحتاج إلى تخزين الـ Token الذي يرجعه الخادم عند تسجيل الدخول وإرساله في كل طلب fetch مثال على ذلك

const token = localStorage.getItem('auth_token');

fetch('https://your-api.com/api/user-data', {
    method: 'GET',
    headers: {
        'Authorization': `Bearer ${token}`,
        'Accept': 'application/json', // مهم جداً حتى يرجع Laravel خطأ 401 بدلاً من التحويل لصفحة Login
        'Content-Type': 'application/json'
    }
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));

ولكن أنت لست بحاجة إلى التعامل مع الـ Bearer Token . حيث يوفر Sanctum ميزة SPA (Single Page Application) Authentication، والتي تعتمد على ملفات تعريف الارتباط (Cookies) المشفرة الخاصة بـ Laravel، وهي أكثر أماناً (لأنها محمية من ثغرات XSS التي يمكنها سرقة الـ localStorage).

كيف استخدم Sanctum فيه حاولت و كل مره يظهر لي unauthenticated

ربما لم تقم بالإعدادات بالشكل المناسب . ولذلك يمكنك الإطلاع على التعليق التالي والتأكد من الخطوات

وتأكد أيضاً من عدم غياب HasApiTokens من نموذج المستخدم. أو نسيان إضافة Accept: application/json في الترويسات، مما يجعل Laravel يرجع استجابة HTML بدلًا من JSON.

للاسف كله هذا سويته ولا زال يظهر لي unauthenticated .

كود جافاسكريبت

async function checkName(bodyForm){
    try{
        const name=await fetch("api/addCompany",{
        method:"POST",
        // credentials:"include",
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json',
            "Authorization": `Bearer ${document.querySelector('input[name=_token]').value}`,// crsf tokenهذا 
            "X-CSRF-Token": document.querySelector('input[name=_token]').value


        },
        body:bodyForm
        });


        const namesJson=await name.json();
        console.log(namesJson)
        // const retName=await namesJson.recName;
        // console.log(retName);
    }
    catch(error)
    {
        return console.log(error.message);


    }


}

المشكلة هي ان token لابد يكون موجود في bearer token في header. و مشكلتي هي هل الافضل حفظ token في session من ناحية امنية؟

موقعي هو token الخاص بالمستخدم عشان يستخدم sanctum ليس معروف للمستخدم. لانه متجر الكتروني و ليس فقط api

ما تحتاجه هو SPA Authentication أي مصادقة تطبيقات الويب أحادية الصفحة، لأنها الأنسب للمواقع التي تعمل على نفس النطاق domain، أي ستسخدم الكوكيز والجلسات.

والخطأ لديك بسبب إرسال الطلب بدون كوكيز الجلسة، فالمتصفح بطبيعته لا يرسل الكوكيز مع طلبات fetch أو axios إلا إن أخبرته بذلك صراحةً، لذلك، لارافل لا يعرف من أنت، فيعتبرك زائراً غير مسجل الدخول.

أي تضمين التالي:

credentials: "include"

ليصبح الكود في قسم <head> في ملف الـ Blade كالتالي:

async function checkName(bodyForm) {
    try {
        const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');


        const response = await fetch("/api/addCompany", {
            method: "POST",
            credentials: "include", 
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
                'X-CSRF-Token': csrfToken, 
            },
            body: bodyForm
        });


        const namesJson = await response.json();
        console.log(namesJson);
    } catch(error) {
        console.log(error.message);
    }
}

وفي ملف .env:

SESSION_DOMAIN=localhost
SANCTUM_STATEFUL_DOMAINS=localhost:8000 # أو الدومين الذي تعمل عليه
SESSION_DRIVER=cookie

وفي ملف ملف config/cors.php:

'paths' => ['api/*', 'sanctum/csrf-cookie', 'login', 'logout'],
'allowed_methods' => ['*'],
'allowed_origins' => ['http://localhost:8000'], // ضع الدومين الخاص بك هنا (بدون slash في النهاية)
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => true,

وقبل أن تقوم بعمل POST لأي مسار محمي مثل addCompany، يجب أن تطلب كوكيز الـ CSRF من Sanctum لتخزينه في المتصفح.

وبالنسبة لمكان حفظ التوكن، فلارافل يقوم بإنشاء كوكي مشفر يسمى laravel_session ويخزنه في متصفح المستخدم كـ HttpOnly Cookie لا يمكن الوصول إليه عبر الجافاسكريبت للحماية من هجمات XSS.

أما Bearer Token فلا تحفظه أبداً في localStorage لأنه عرضة للاختراق بسهولة عبر هجمات XSS، قم بإعادة الـ Token من الـ API وجعل الـ Frontend يخزنه في HttpOnly Cookie، أو استخدام آلية لارافل لـ API Tokens.