هدرهای درخواست HTTP اضافی اضافه کنید

درخواست های HTTP حاوی سرصفحه هایی مانند User-Agent یا Content-Type هستند. به غیر از سرصفحه‌های پیوست شده توسط مرورگرها، برنامه‌های Android ممکن است سرصفحه‌های اضافی مانند Cookie یا Referrer را از طریق EXTRA_HEADERS Intent اضافه کنند. به دلایل امنیتی، Chrome برخی از هدرهای اضافی را بسته به نحوه و مکان راه اندازی یک هدف فیلتر می کند.

درخواست‌های متقاطع به یک لایه امنیتی اضافی نیاز دارند زیرا مشتری و سرور متعلق به یک طرف نیستند. این راهنما درباره راه‌اندازی چنین درخواست‌هایی از طریق برگه‌های سفارشی Chrome، یعنی اهداف راه‌اندازی شده از برنامه‌هایی که URL را در برگه مرورگر باز می‌کنند، بحث می‌کند. تا Chrome 83، توسعه‌دهندگان می‌توانستند هنگام راه‌اندازی یک تب سفارشی، هر سرصفحه‌ای را اضافه کنند. از نسخه 83 به بعد، Chrome شروع به فیلتر کردن همه سرصفحه‌های تأییدشده با منبع متقاطع کرد، زیرا سرصفحه‌های تأیید نشده خطر امنیتی ایجاد می‌کنند. با شروع Chrome 86، زمانی که سرور و مشتری با استفاده از پیوند دارایی دیجیتال مرتبط هستند، می‌توان سرصفحه‌های تایید نشده را به درخواست‌های متقاطع پیوست کرد. این رفتار در جدول زیر خلاصه شده است:

نسخه کروم سرصفحه های CORS مجاز است
قبل از کروم 83 تایید شده، تایید نشده
کروم 83 تا کروم 85 تایید شده
از Chrome 86 به بعد تأیید شده، زمانی که پیوند دارایی دیجیتال تنظیم می شود، تأیید نشده است

جدول 1: فیلتر کردن هدرهای CORS تایید نشده.

این مقاله نحوه راه‌اندازی یک ارتباط تأیید شده بین سرور و کلاینت و استفاده از آن برای ارسال سرصفحه‌های http تأیید شده و همچنین غیر تأیید شده را نشان می‌دهد. می توانید برای کد به قسمت Add Extra Headers to Custom Tab Intent بروید.

پس زمینه

سرصفحه های درخواست CORS تایید شده در مقابل غیر تایید شده

به اشتراک گذاری منابع متقاطع (CORS) به یک برنامه وب از یک مبدأ اجازه می دهد تا منابعی با مبدا متفاوت درخواست کند. فهرست سرصفحه‌های تایید شده توسط CORS در استاندارد HTML نگهداری می‌شود. نمونه سرصفحه های تایید شده در جدول بعدی نشان داده شده است:

سربرگ توضیحات
قبول-زبان زبان های طبیعی را که مشتری می فهمد تبلیغ می کند
محتوا-زبان زبان در نظر گرفته شده برای مخاطب فعلی را توصیف می کند
نوع محتوا نوع رسانه منبع را نشان می دهد

جدول 2.: نمونه سرصفحه های CORS تایید شده.

هدرهای تایید شده ایمن در نظر گرفته می شوند زیرا حاوی اطلاعات حساس کاربر نیستند و بعید است که سرور را وادار به انجام عملیات آسیب رسان بالقوه کنند.

نمونه هایی از هدرهای تایید نشده در جدول زیر نشان داده شده است:

سربرگ توضیحات
نشان حامل کلاینت را در سرور احراز هویت می کند
منشاء مبدأ درخواست را نشان می دهد
کوکی حاوی کوکی هایی است که توسط سرور تنظیم شده است

جدول 3.: نمونه سرصفحه های CORS تایید نشده.

ضمیمه سرصفحه‌های تایید نشده به درخواست‌های CORS توسط استاندارد HTML ممنوع است و سرورها فرض می‌کنند که درخواست‌های متقاطع فقط حاوی سرصفحه‌های تایید شده هستند. ارسال سرصفحه‌های تأیید نشده از دامنه‌های متقاطع به برنامه‌های شخص ثالث مخرب اجازه می‌دهد تا سرصفحه‌هایی ایجاد کنند که از کوکی‌های کاربر که Chrome (یا مرورگر دیگری) ذخیره می‌کند و به درخواست‌ها پیوست می‌کند، سوء استفاده می‌کنند. کوکی ها می توانند تراکنش های مخرب سرور را تأیید کنند که در غیر این صورت امکان پذیر نبود.

پیوست کردن سرصفحه‌های تأیید شده CORS به درخواست‌های برگه‌های سفارشی

تب های سفارشی روشی ویژه برای راه اندازی صفحات وب در یک برگه مرورگر سفارشی شده است. اهداف Tab سفارشی را می توان با استفاده از CustomTabsIntent.Builder() ایجاد کرد. همچنین می‌توانید با استفاده از یک Bundle با پرچم Browser.EXTRA_HEADERS سرصفحه‌ها را به این اهداف پیوست کنید:

CustomTabsIntent intent = new CustomTabsIntent.Builder(session).build();

Bundle headers = new Bundle();
headers.putString("bearer-token", "Some token");
headers.putString("redirect-url", "Some redirect url");   
intent.intent.putExtra(Browser.EXTRA_HEADERS, headers);

intent.launchUrl(Activity.this, Uri.parse("http://www.google.com"));

ما همیشه می‌توانیم سرصفحه‌های تأیید شده را به درخواست‌های CORS برگه‌های سفارشی پیوست کنیم. با این حال، کروم به طور پیش‌فرض سرصفحه‌های تایید نشده را فیلتر می‌کند. اگرچه سایر مرورگرها ممکن است رفتار متفاوتی داشته باشند، توسعه دهندگان باید انتظار داشته باشند که هدرهای تایید نشده به طور کلی مسدود شوند.

راه پشتیبانی شده برای گنجاندن سرصفحه‌های تایید نشده در برگه‌های سفارشی این است که ابتدا اتصال متقاطع را با استفاده از یک پیوند دسترسی دیجیتال تأیید کنید. بخش بعدی نحوه تنظیم و راه‌اندازی یک برنامه Custom Tabs با هدرهای مورد نیاز را نشان می‌دهد.

اضافه کردن هدرهای اضافی به مقاصد برگه سفارشی

برای اجازه دادن به سرصفحه‌های تایید نشده از طریق اهداف Tab سفارشی، لازم است یک پیوند دارایی دیجیتال بین اندروید و برنامه وب تنظیم شود که تأیید کند نویسنده هر دو برنامه را دارد.

راهنمای رسمی را برای راه اندازی پیوند دارایی دیجیتال دنبال کنید. برای رابطه پیوند از "delegate_permission/common.use_as_origin" استفاده کنید که نشان می‌دهد هر دو برنامه پس از تأیید پیوند به یک مبدا تعلق دارند.

با سرصفحه‌های اضافی، یک Tab Custom Intent ایجاد کنید

راه های متعددی برای ایجاد یک هدف Tabs سفارشی وجود دارد. می‌توانید با افزودن کتابخانه به وابستگی‌های ساخت، از سازنده موجود در androidX استفاده کنید:

implementation 'androidx.browser:browser:1.2.0'

هدف را بسازید و هدرهای اضافی اضافه کنید:

CustomTabsIntent constructExtraHeadersIntent(CustomTabsSession session) {
    CustomTabsIntent intent = new CustomTabsIntent.Builder(session).build();

    // Example non-cors-approvelisted headers.
    Bundle headers = new Bundle();
    headers.putString("bearer-token", "Some token");
    headers.putString("redirect-url", "Some redirect url");
    intent.intent.putExtra(Browser.EXTRA_HEADERS, headers);
    return intent;
}

یک اتصال Custom Tabs برای تنظیم CustomTabsSession بین برنامه و برگه Chrome استفاده می‌شود. ما به جلسه نیاز داریم تا تأیید کنیم که برنامه و برنامه وب متعلق به یک مبدا هستند. تأیید فقط در صورتی انجام می شود که پیوندهای دارایی دیجیتال به درستی تنظیم شده باشند.

تشویق می شود که CustomTabsClient.warmup() را فراخوانی کنید. این به برنامه مرورگر اجازه می دهد تا در پس زمینه از قبل مقداردهی شود و روند باز کردن URL را سرعت بخشد.

// Set up a connection that warms up and validates a session.
CustomTabsServiceConnection connection = new CustomTabsServiceConnection() {
    @Override
    public void onCustomTabsServiceConnected(@NonNull ComponentName name, 
        @NonNull CustomTabsClient client) {
        // Create session after service connected.
        mSession = client.newSession(callback);
        client.warmup(0);
        // Validate the session as the same origin to allow cross origin headers.
        mSession.validateRelationship(CustomTabsService.RELATION_USE_AS_ORIGIN, 
            Uri.parse(url), null);
    }
    @Override
    public void onServiceDisconnected(ComponentName componentName) { }
};

یک Callback تنظیم کنید که پس از اعتبار سنجی، Intent را راه اندازی می کند

CustomTabsCallback به جلسه منتقل شد. ما onRelationshipValidationResult() آن را برای راه‌اندازی CustomTabsIntent که قبلاً ایجاد شده بود، پس از موفقیت در تأیید مبدا تنظیم کردیم.

// Set up a callback that launches the intent after session validated.
CustomTabsCallback callback = new CustomTabsCallback() {
    @Override
    public void onRelationshipValidationResult(int relation, @NonNull Uri requestedOrigin, 
        boolean result, @Nullable Bundle extras) {
        // Launch custom tabs intent after session was validated as the same origin.
        CustomTabsIntent intent = constructExtraHeadersIntent(mSession);
        intent.launchUrl(MainActivity.this, Uri.parse(url));
    }
};

اتصال سرویس برگه های سفارشی را متصل کنید

اتصال سرویس، سرویس را راه‌اندازی می‌کند و onCustomTabsServiceConnected() در نهایت فراخوانی می‌شود. فراموش نکنید که سرویس را به طور مناسب باز کنید. اتصال و عدم اتصال معمولاً در متدهای چرخه حیات فعالیت onStart() و onStop() انجام می شود.

// Bind the custom tabs service connection.
// Call this in onStart()
CustomTabsClient.bindCustomTabsService(this,
    CustomTabsClient.getPackageName(MainActivity.this, null), connection);

// …
// Unbind the custom tabs service.
// Call this in onStop().
unbindService(connection);

کد برنامه آزمایشی

شما می توانید جزئیات بیشتر در مورد Custom Tabs Service را در اینجا بیابید. برای یک برنامه نمونه کار به مخزن GitHub کمک مرورگر اندروید مراجعه کنید.

خلاصه

این راهنما نحوه افزودن سرصفحه دلخواه به درخواست‌های CORS را نشان می‌دهد. سرصفحه های تایید شده را می توان به هر درخواست CORS برگه های سفارشی پیوست کرد. سرصفحه‌های تایید نشده معمولاً در درخواست‌های CORS ناامن تلقی می‌شوند و کروم آن‌ها را به‌طور پیش‌فرض فیلتر می‌کند. پیوست کردن آنها فقط برای کلاینت‌ها و سرورهایی از همان مبدا مجاز است که توسط پیوند دارایی دیجیتال تأیید شده است.