সততার রায়

এই পৃষ্ঠাটি বর্ণনা করে যে কিভাবে ব্যাখ্যা করা যায় এবং ফিরে আসা অখণ্ডতার রায়ের সাথে কাজ করা যায়। আপনি একটি স্ট্যান্ডার্ড বা ক্লাসিক API অনুরোধ করুন না কেন, একই বিষয়বস্তু সহ একই বিন্যাসে অখণ্ডতার রায় ফেরত দেওয়া হয়। অখণ্ডতার রায় ডিভাইস, অ্যাপ এবং অ্যাকাউন্টের বৈধতা সম্পর্কে তথ্য যোগাযোগ করে। আপনার অ্যাপের সার্ভার একটি ডিক্রিপ্ট করা, যাচাইকৃত রায়ে ফলাফল পেলোড ব্যবহার করতে পারে আপনার অ্যাপে একটি নির্দিষ্ট ক্রিয়া বা অনুরোধের সাথে কীভাবে এগিয়ে যেতে হবে তা নির্ধারণ করতে।

অখণ্ডতা রায় বিন্যাস ফেরত

পেলোড হল প্লেইন-টেক্সট JSON এবং এতে ডেভেলপার-প্রদত্ত তথ্যের পাশাপাশি অখণ্ডতার সংকেত রয়েছে।

সাধারণ পেলোড গঠন নিম্নরূপ:

{
  requestDetails: { ... }
  appIntegrity: { ... }
  deviceIntegrity: { ... }
  accountDetails: { ... }
  environmentDetails: { ... }
}

প্রতিটি অখণ্ডতার রায় পরীক্ষা করার আগে আপনাকে অবশ্যই প্রথমে requestDetails ক্ষেত্রের মানগুলি মূল অনুরোধের সাথে মেলে কিনা তা পরীক্ষা করতে হবে। নিম্নলিখিত বিভাগগুলি প্রতিটি ক্ষেত্রকে আরও বিশদে বর্ণনা করে।

বিশদ ক্ষেত্র অনুরোধ করুন

requestDetails ফিল্ডে রিকোয়েস্ট সম্পর্কে তথ্য রয়েছে, যার মধ্যে রয়েছে স্ট্যান্ডার্ড অনুরোধের জন্য requestHash ডেভেলপার-প্রদত্ত তথ্য এবং ক্লাসিক অনুরোধের জন্য nonce

স্ট্যান্ডার্ড API অনুরোধের জন্য:

requestDetails: {
  // Application package name this attestation was requested for.
  // Note that this field might be spoofed in the middle of the request.
  requestPackageName: "com.package.name"
  // Request hash provided by the developer.
  requestHash: "aGVsbG8gd29scmQgdGhlcmU"
  // The timestamp in milliseconds when the integrity token
  // was requested.
  timestampMillis: "1675655009345"
}

এই মানগুলি মূল অনুরোধের সাথে মেলে। তাই, JSON পেলোডের requestDetails অংশ যাচাই করে নিশ্চিত করুন যে requestPackageName এবং requestHash মূল অনুরোধে যা পাঠানো হয়েছে তার সাথে মেলে, যেমনটি নিম্নলিখিত কোড স্নিপেটে দেখানো হয়েছে:

কোটলিন

val requestDetails = JSONObject(payload).getJSONObject("requestDetails")
val requestPackageName = requestDetails.getString("requestPackageName")
val requestHash = requestDetails.getString("requestHash")
val timestampMillis = requestDetails.getLong("timestampMillis")
val currentTimestampMillis = ...

// Ensure the token is from your app.
if (!requestPackageName.equals(expectedPackageName)
        // Ensure the token is for this specific request
    || !requestHash.equals(expectedRequestHash)
        // Ensure the freshness of the token.
    || currentTimestampMillis - timestampMillis > ALLOWED_WINDOW_MILLIS) {
        // The token is invalid! See below for further checks.
        ...
}

জাভা

RequestDetails requestDetails =
    decodeIntegrityTokenResponse
    .getTokenPayloadExternal()
    .getRequestDetails();
String requestPackageName = requestDetails.getRequestPackageName();
String requestHash = requestDetails.getRequestHash();
long timestampMillis = requestDetails.getTimestampMillis();
long currentTimestampMillis = ...;

// Ensure the token is from your app.
if (!requestPackageName.equals(expectedPackageName)
        // Ensure the token is for this specific request.
    || !requestHash.equals(expectedRequestHash)
        // Ensure the freshness of the token.
    || currentTimestampMillis - timestampMillis > ALLOWED_WINDOW_MILLIS) {
        // The token is invalid! See below for further checks.
        ...
}

ক্লাসিক API অনুরোধের জন্য:

requestDetails: {
  // Application package name this attestation was requested for.
  // Note that this field might be spoofed in the middle of the
  // request.
  requestPackageName: "com.package.name"
  // base64-encoded URL-safe no-wrap nonce provided by the developer.
  nonce: "aGVsbG8gd29scmQgdGhlcmU"
  // The timestamp in milliseconds when the request was made
  // (computed on the server).
  timestampMillis: "1617893780"
}

এই মানগুলি মূল অনুরোধের সাথে মেলে। অতএব, JSON পেলোডের requestDetails অংশ যাচাই করুন যাতে নিম্নলিখিত কোড স্নিপেটে দেখানো হয়েছে, মূল অনুরোধে যা পাঠানো হয়েছে তার সাথে requestPackageName এবং মেলে nonce :

কোটলিন

val requestDetails = JSONObject(payload).getJSONObject("requestDetails")
val requestPackageName = requestDetails.getString("requestPackageName")
val nonce = requestDetails.getString("nonce")
val timestampMillis = requestDetails.getLong("timestampMillis")
val currentTimestampMillis = ...

// Ensure the token is from your app.
if (!requestPackageName.equals(expectedPackageName)
        // Ensure the token is for this specific request. See 'Generate a nonce'
        // section of the doc on how to store/compute the expected nonce.
    || !nonce.equals(expectedNonce)
        // Ensure the freshness of the token.
    || currentTimestampMillis - timestampMillis > ALLOWED_WINDOW_MILLIS) {
        // The token is invalid! See below for further checks.
        ...
}

জাভা

JSONObject requestDetails =
    new JSONObject(payload).getJSONObject("requestDetails");
String requestPackageName = requestDetails.getString("requestPackageName");
String nonce = requestDetails.getString("nonce");
long timestampMillis = requestDetails.getLong("timestampMillis");
long currentTimestampMillis = ...;

// Ensure the token is from your app.
if (!requestPackageName.equals(expectedPackageName)
        // Ensure the token is for this specific request. See 'Generate a nonce'
        // section of the doc on how to store/compute the expected nonce.
    || !nonce.equals(expectedNonce)
        // Ensure the freshness of the token.
    || currentTimestampMillis - timestampMillis > ALLOWED_WINDOW_MILLIS) {
        // The token is invalid! See below for further checks.
        ...
}

অ্যাপ্লিকেশন অখণ্ডতা ক্ষেত্র

appIntegrity ফিল্ডে প্যাকেজ-সম্পর্কিত তথ্য রয়েছে।

appIntegrity: {
  // PLAY_RECOGNIZED, UNRECOGNIZED_VERSION, or UNEVALUATED.
  appRecognitionVerdict: "PLAY_RECOGNIZED"
  // The package name of the app.
  // This field is populated iff appRecognitionVerdict != UNEVALUATED.
  packageName: "com.package.name"
  // The sha256 digest of app certificates (base64-encoded URL-safe).
  // This field is populated iff appRecognitionVerdict != UNEVALUATED.
  certificateSha256Digest: ["6a6a1474b5cbbb2b1aa57e0bc3"]
  // The version of the app.
  // This field is populated iff appRecognitionVerdict != UNEVALUATED.
  versionCode: "42"
}

appRecognitionVerdict নিম্নলিখিত মান থাকতে পারে:

PLAY_RECOGNIZED
অ্যাপ এবং সার্টিফিকেট Google Play দ্বারা বিতরণ করা সংস্করণের সাথে মেলে।
UNRECOGNIZED_VERSION
সার্টিফিকেট বা প্যাকেজের নাম Google Play রেকর্ডের সাথে মেলে না।
UNEVALUATED
অ্যাপ্লিকেশন অখণ্ডতা মূল্যায়ন করা হয়নি. একটি প্রয়োজনীয় প্রয়োজনীয়তা মিস হয়েছে, যেমন ডিভাইসটি যথেষ্ট বিশ্বাসযোগ্য নয়।

আপনার দ্বারা তৈরি করা একটি অ্যাপ দ্বারা টোকেন তৈরি করা হয়েছে তা নিশ্চিত করতে, নিম্নলিখিত কোড স্নিপেটে দেখানো হিসাবে অ্যাপ্লিকেশনের অখণ্ডতা প্রত্যাশিত কিনা তা যাচাই করুন:

কোটলিন

val appIntegrity = JSONObject(payload).getJSONObject("appIntegrity")
val appRecognitionVerdict = appIntegrity.getString("appRecognitionVerdict")

if (appRecognitionVerdict == "PLAY_RECOGNIZED") {
    // Looks good!
}

জাভা

JSONObject appIntegrity =
    new JSONObject(payload).getJSONObject("appIntegrity");
String appRecognitionVerdict =
    appIntegrity.getString("appRecognitionVerdict");

if (appRecognitionVerdict.equals("PLAY_RECOGNIZED")) {
    // Looks good!
}

এছাড়াও আপনি অ্যাপ প্যাকেজের নাম, অ্যাপ সংস্করণ এবং অ্যাপ শংসাপত্র ম্যানুয়ালি চেক করতে পারেন।

ডিভাইস অখণ্ডতা ক্ষেত্র

deviceIntegrity ফিল্ডে একটি একক মান থাকতে পারে, deviceRecognitionVerdict , যেটিতে এক বা একাধিক লেবেল রয়েছে যা প্রতিনিধিত্ব করে যে একটি ডিভাইস কতটা ভালোভাবে অ্যাপের অখণ্ডতা প্রয়োগ করতে পারে৷ যদি কোনো ডিভাইস কোনো লেবেলের মানদণ্ড পূরণ না করে, deviceIntegrity ক্ষেত্রটি খালি থাকে।

deviceIntegrity: {
  // "MEETS_DEVICE_INTEGRITY" is one of several possible values.
  deviceRecognitionVerdict: ["MEETS_DEVICE_INTEGRITY"]
}

ডিফল্টরূপে, deviceRecognitionVerdict নিম্নলিখিতগুলি থাকতে পারে:

MEETS_DEVICE_INTEGRITY
অ্যাপটি Google Play পরিষেবা সহ একটি Android-চালিত ডিভাইসে চলছে৷ ডিভাইসটি সিস্টেম ইন্টিগ্রিটি চেক পাস করে এবং Android সামঞ্জস্যের প্রয়োজনীয়তা পূরণ করে।
খালি (একটি ফাঁকা মান)
অ্যাপ্লিকেশানটি এমন একটি ডিভাইসে চলছে যেখানে আক্রমণের লক্ষণ রয়েছে (যেমন API হুকিং) বা সিস্টেম আপস (যেমন রুট করা) বা অ্যাপটি কোনও শারীরিক ডিভাইসে চলছে না (যেমন একটি এমুলেটর যা Google Play অখণ্ডতা পাস করে না চেক)।

টোকেনটি একটি বিশ্বস্ত ডিভাইস থেকে এসেছে তা নিশ্চিত করার জন্য, নিম্নলিখিত কোড স্নিপেটে দেখানো হিসাবে deviceRecognitionVerdict প্রত্যাশা অনুযায়ী যাচাই করুন:

কোটলিন

val deviceIntegrity =
    JSONObject(payload).getJSONObject("deviceIntegrity")
val deviceRecognitionVerdict =
    if (deviceIntegrity.has("deviceRecognitionVerdict")) {
        deviceIntegrity.getJSONArray("deviceRecognitionVerdict").toString()
    } else {
        ""
    }

if (deviceRecognitionVerdict.contains("MEETS_DEVICE_INTEGRITY")) {
    // Looks good!
}

জাভা

JSONObject deviceIntegrity =
    new JSONObject(payload).getJSONObject("deviceIntegrity");
String deviceRecognitionVerdict =
    deviceIntegrity.has("deviceRecognitionVerdict")
    ? deviceIntegrity.getJSONArray("deviceRecognitionVerdict").toString()
    : "";

if (deviceRecognitionVerdict.contains("MEETS_DEVICE_INTEGRITY")) {
    // Looks good!
}

আপনার টেস্টিং ডিভাইস মিটিং ডিভাইস ইন্টিগ্রিটি নিয়ে সমস্যা হলে, নিশ্চিত করুন যে ফ্যাক্টরি রম ইনস্টল করা আছে (উদাহরণস্বরূপ, ডিভাইস রিসেট করে) এবং বুটলোডার লক করা আছে। এছাড়াও আপনি আপনার Play Console-এ Play Integrity API পরীক্ষা তৈরি করতে পারেন।

শর্তাধীন ডিভাইস লেবেল

যদি আপনার অ্যাপটি PC-এর জন্য Google Play Games- এ প্রকাশ করা হয়, তাহলে deviceRecognitionVerdict নিম্নলিখিত লেবেলও থাকতে পারে:

MEETS_VIRTUAL_INTEGRITY
অ্যাপটি Google Play পরিষেবাগুলির সাথে একটি Android-চালিত এমুলেটরে চলছে৷ এমুলেটর সিস্টেম অখণ্ডতা পরীক্ষা পাস করে এবং মূল Android সামঞ্জস্যের প্রয়োজনীয়তা পূরণ করে।

ঐচ্ছিক ডিভাইস তথ্য

আপনি যদি অখণ্ডতার রায়ে অতিরিক্ত লেবেল পেতে বেছে নেন , তাহলে deviceRecognitionVerdict নিম্নলিখিত অতিরিক্ত লেবেল থাকতে পারে:

MEETS_BASIC_INTEGRITY
অ্যাপটি এমন একটি ডিভাইসে চলছে যা মৌলিক সিস্টেম ইন্টিগ্রিটি চেক পাস করে এবং অ্যান্ড্রয়েড 13 বা তার পরবর্তী ডিভাইসের জন্য অ্যান্ড্রয়েড প্ল্যাটফর্ম কী প্রত্যয়ন প্রয়োজন। ডিভাইসটি Android সামঞ্জস্যের প্রয়োজনীয়তা পূরণ নাও করতে পারে এবং Google Play পরিষেবাগুলি চালানোর জন্য অনুমোদিত নাও হতে পারে৷ উদাহরণস্বরূপ, ডিভাইসটি Android এর একটি অচেনা সংস্করণ চালাতে পারে, একটি আনলক করা বুটলোডার থাকতে পারে, বুটটি যাচাই করা হয়নি বা প্রস্তুতকারকের দ্বারা প্রত্যয়িত নাও থাকতে পারে৷
MEETS_STRONG_INTEGRITY
অ্যাপটি Google Play পরিষেবাগুলির সাথে একটি Android-চালিত ডিভাইসে চলছে এবং সিস্টেমের অখণ্ডতার একটি দৃঢ় গ্যারান্টি রয়েছে যেমন বুট অখণ্ডতার একটি হার্ডওয়্যার-সমর্থিত প্রমাণ এবং Android 13 বা তার পরবর্তী ডিভাইসগুলির জন্য গত বছরে একটি নিরাপত্তা আপডেট থাকা প্রয়োজন৷ ডিভাইসটি সিস্টেম ইন্টিগ্রিটি চেক পাস করে এবং Android সামঞ্জস্যের প্রয়োজনীয়তা পূরণ করে।

একটি একক ডিভাইস ডিভাইসের অখণ্ডতার রায়ে একাধিক ডিভাইস লেবেল ফিরিয়ে দেবে যদি লেবেলের প্রতিটি মানদণ্ড পূরণ করা হয়।

সাম্প্রতিক ডিভাইস কার্যকলাপ

আপনি সাম্প্রতিক ডিভাইস ক্রিয়াকলাপও বেছে নিতে পারেন, যা আপনাকে বলে যে আপনার অ্যাপটি গত ঘন্টায় কতবার একটি নির্দিষ্ট ডিভাইসে একটি অখণ্ডতা টোকেন অনুরোধ করেছে৷ আপনি অপ্রত্যাশিত, হাইপারঅ্যাকটিভ ডিভাইসগুলির বিরুদ্ধে আপনার অ্যাপকে রক্ষা করতে সাম্প্রতিক ডিভাইস কার্যকলাপ ব্যবহার করতে পারেন যা একটি সক্রিয় আক্রমণের ইঙ্গিত হতে পারে। আপনি প্রতি ঘন্টায় একটি অখণ্ডতা টোকেন অনুরোধ করার জন্য একটি সাধারণ ডিভাইসে কতবার আপনার অ্যাপ ইনস্টল করার আশা করছেন তার উপর ভিত্তি করে আপনি প্রতিটি সাম্প্রতিক ডিভাইসের কার্যকলাপের স্তরে কতটা বিশ্বাস করবেন তা নির্ধারণ করতে পারেন।

আপনি যদি recentDeviceActivity পাওয়ার জন্য নির্বাচন করেন তবে deviceIntegrity ক্ষেত্রের দুটি মান থাকবে:

deviceIntegrity: {
  deviceRecognitionVerdict: ["MEETS_DEVICE_INTEGRITY"]
  recentDeviceActivity: {
    // "LEVEL_2" is one of several possible values.
    deviceActivityLevel: "LEVEL_2"
  }
}

deviceActivityLevel লেভেলের সংজ্ঞাগুলি মোডগুলির মধ্যে আলাদা এবং নিম্নলিখিত মানগুলির মধ্যে একটি থাকতে পারে:

সাম্প্রতিক ডিভাইস কার্যকলাপ স্তর এই ডিভাইসে প্রতি অ্যাপের শেষ ঘণ্টায় স্ট্যান্ডার্ড API ইন্টিগ্রিটি টোকেন অনুরোধ এই ডিভাইসে ক্লাসিক এপিআই ইন্টিগ্রিটি টোকেন অনুরোধ প্রতি অ্যাপের শেষ ঘণ্টায়
LEVEL_1 (সর্বনিম্ন) 10 বা তার কম 5 বা তার কম
LEVEL_2 11 থেকে 25 এর মধ্যে 6 থেকে 10 এর মধ্যে
LEVEL_3 26 থেকে 50 এর মধ্যে 11 এবং 15 এর মধ্যে
LEVEL_4 (সর্বোচ্চ) 50 এর বেশি 15 এর বেশি
UNEVALUATED সাম্প্রতিক ডিভাইস কার্যকলাপ মূল্যায়ন করা হয়নি. এটি ঘটতে পারে কারণ:
  • ডিভাইসটি যথেষ্ট বিশ্বাসযোগ্য নয়।
  • ডিভাইসে ইনস্টল করা আপনার অ্যাপের সংস্করণ Google Play-এর কাছে অজানা।
  • ডিভাইসে প্রযুক্তিগত সমস্যা।

ডিভাইসের বৈশিষ্ট্য

আপনি ডিভাইসের বৈশিষ্ট্যগুলিতেও নির্বাচন করতে পারেন, যা ডিভাইসে চলমান Android OS এর Android SDK সংস্করণকে বলে৷ ভবিষ্যতে, এটি অন্যান্য ডিভাইস বৈশিষ্ট্যগুলির সাথে প্রসারিত হতে পারে।

SDK সংস্করণের মান হল Android SDK সংস্করণ নম্বর যা Build.VERSION_CODES এ সংজ্ঞায়িত করা হয়েছে। একটি প্রয়োজনীয় প্রয়োজনীয়তা মিস হলে SDK সংস্করণটি মূল্যায়ন করা হয় না। এই ক্ষেত্রে, sdkVersion ক্ষেত্রটি সেট করা নেই; এইভাবে, deviceAttributes ক্ষেত্রটি খালি। এটি ঘটতে পারে কারণ:

  • ডিভাইসটি যথেষ্ট বিশ্বাসযোগ্য নয়।
  • ডিভাইসে ইনস্টল করা আপনার অ্যাপের সংস্করণ Google Play-এর কাছে অজানা।
  • ডিভাইসে প্রযুক্তিগত সমস্যা ছিল।

আপনি যদি deviceAttributes পাওয়ার জন্য নির্বাচন করেন, তাহলে deviceIntegrity ক্ষেত্রে নিম্নলিখিত অতিরিক্ত ক্ষেত্র থাকবে:

deviceIntegrity: {
  deviceRecognitionVerdict: ["MEETS_DEVICE_INTEGRITY"]
  deviceAttributes: {
    // 33 is one possible value, which represents Android 13 (Tiramisu).
    sdkVersion: 33
  }
}

SDK সংস্করণের মূল্যায়ন না করা হলে, deviceAttributes ক্ষেত্রটি নিম্নলিখিত হিসাবে সেট করা হবে:

deviceIntegrity: {
  deviceRecognitionVerdict: ["MEETS_DEVICE_INTEGRITY"]
  deviceAttributes: {}  // sdkVersion field is not set.
}

অ্যাকাউন্টের বিবরণ ক্ষেত্র

accountDetails ক্ষেত্রটিতে একটি একক মান রয়েছে, appLicensingVerdict , যা ডিভাইসে সাইন ইন করা ব্যবহারকারীর অ্যাকাউন্টের জন্য অ্যাপের Google Play লাইসেন্সিং স্থিতিকে প্রতিনিধিত্ব করে। যদি ব্যবহারকারীর অ্যাকাউন্টে অ্যাপের জন্য প্লে লাইসেন্স থাকে, তার মানে তারা এটি ডাউনলোড করেছে বা Google Play থেকে কিনেছে।

accountDetails: {
  // This field can be LICENSED, UNLICENSED, or UNEVALUATED.
  appLicensingVerdict: "LICENSED"
}

appLicensingVerdict নিম্নলিখিত মানগুলির মধ্যে একটি থাকতে পারে:

LICENSED
ব্যবহারকারীর একটি অ্যাপ এনটাইটেলমেন্ট আছে। অন্য কথায়, ব্যবহারকারী তাদের ডিভাইসে Google Play থেকে আপনার অ্যাপ ইনস্টল বা আপডেট করেছেন।
UNLICENSED
ব্যবহারকারীর কোনো অ্যাপ এনটাইটেলমেন্ট নেই। এটি ঘটে যখন, উদাহরণস্বরূপ, ব্যবহারকারী আপনার অ্যাপটিকে সাইডলোড করে বা Google Play থেকে এটি অর্জন করে না। আপনি এর প্রতিকারের জন্য ব্যবহারকারীদের GET_LICENSED ডায়ালগ দেখাতে পারেন৷
UNEVALUATED

লাইসেন্সিং বিশদ মূল্যায়ন করা হয়নি কারণ একটি প্রয়োজনীয় প্রয়োজনীয়তা মিস করা হয়েছিল।

এটি নিম্নলিখিত সহ বিভিন্ন কারণে ঘটতে পারে:

  • ডিভাইসটি যথেষ্ট বিশ্বাসযোগ্য নয়।
  • ডিভাইসে ইনস্টল করা আপনার অ্যাপের সংস্করণ Google Play-এর কাছে অজানা।
  • ব্যবহারকারী Google Play-এ সাইন ইন করেননি।

ব্যবহারকারীর কাছে আপনার অ্যাপের জন্য একটি অ্যাপ এনটাইটেলমেন্ট আছে কিনা তা যাচাই করতে, নিচের কোড স্নিপেটে দেখানো appLicensingVerdict প্রত্যাশিতভাবে আছে কিনা তা যাচাই করুন:

কোটলিন

val accountDetails = JSONObject(payload).getJSONObject("accountDetails")
val appLicensingVerdict = accountDetails.getString("appLicensingVerdict")

if (appLicensingVerdict == "LICENSED") {
    // Looks good!
}

জাভা

JSONObject accountDetails =
    new JSONObject(payload).getJSONObject("accountDetails");
String appLicensingVerdict = accountDetails.getString("appLicensingVerdict");

if (appLicensingVerdict.equals("LICENSED")) {
    // Looks good!
}

পরিবেশ বিশদ ক্ষেত্র

আপনি পরিবেশ সম্পর্কে অতিরিক্ত সংকেত নির্বাচন করতে পারেন। স্ক্রীন ক্যাপচার, ডিসপ্লে ওভারলে বা ডিভাইস নিয়ন্ত্রণ করতে ব্যবহার করা যেতে পারে এমন অন্যান্য অ্যাপ চলমান থাকলে অ্যাপ অ্যাক্সেস ঝুঁকি আপনার অ্যাপকে বলে। Play Protect এর রায় আপনাকে বলে যে ডিভাইসে Google Play Protect সক্ষম আছে কিনা এবং এটি পরিচিত ম্যালওয়্যার খুঁজে পেয়েছে কিনা।

আপনি যদি আপনার Google Play Console-এ অ্যাপ অ্যাক্সেস ঝুঁকি রায় বা Play Protect রায় বেছে নিয়ে থাকেন, তাহলে আপনার API প্রতিক্রিয়া environmentDetails ক্ষেত্র অন্তর্ভুক্ত করবে। environmentDetails ক্ষেত্রে দুটি মান থাকতে পারে, appAccessRiskVerdict এবং playProtectVerdict

অ্যাপ অ্যাক্সেস ঝুঁকি রায়

একবার সক্ষম হয়ে গেলে, Play Integrity API পেলোডে environmentDetails ক্ষেত্রটিতে নতুন অ্যাপ অ্যাক্সেস ঝুঁকির রায় থাকবে।

{
  requestDetails: { ... }
  appIntegrity: { ... }
  deviceIntegrity: { ... }
  accountDetails: { ... }
  environmentDetails: {
      appAccessRiskVerdict: {
          // This field contains one or more responses, for example the following.
          appsDetected: ["KNOWN_INSTALLED", "UNKNOWN_INSTALLED", "UNKNOWN_CAPTURING"]
      }
 }
}

অ্যাপ অ্যাক্সেস ঝুঁকি মূল্যায়ন করা হলে, appAccessRiskVerdict এক বা একাধিক প্রতিক্রিয়ার সাথে appsDetected ক্ষেত্র অ্যাপ রয়েছে। এই প্রতিক্রিয়াগুলি সনাক্ত করা অ্যাপগুলির ইনস্টল উত্সের উপর নির্ভর করে নিম্নলিখিত দুটি গ্রুপের মধ্যে একটিতে পড়ে:

  • প্লে বা সিস্টেম অ্যাপস : যে অ্যাপগুলি Google Play দ্বারা ইনস্টল করা হয়েছে বা ডিভাইসের সিস্টেম পার্টিশনে ডিভাইস নির্মাতার দ্বারা প্রিলোড করা হয়েছে ( FLAG_SYSTEM এর মাধ্যমে চিহ্নিত)। এই ধরনের অ্যাপ্লিকেশানগুলির প্রতিক্রিয়াগুলি KNOWN_ দ্বারা উপসর্গযুক্ত।

  • অন্যান্য অ্যাপস : যে অ্যাপগুলি Google Play দ্বারা ইনস্টল করা হয় না। এটি ডিভাইস প্রস্তুতকারকের দ্বারা সিস্টেম পার্টিশনে প্রিলোড করা অ্যাপগুলিকে বাদ দেয়৷ এই ধরনের অ্যাপ্লিকেশানগুলির প্রতিক্রিয়া UNKNOWN_ দ্বারা উপসর্গযুক্ত।

নিম্নলিখিত প্রতিক্রিয়াগুলি ফেরত দেওয়া যেতে পারে:

KNOWN_INSTALLED , UNKNOWN_INSTALLED
সংশ্লিষ্ট ইনস্টল সোর্সের সাথে মেলে এমন অ্যাপ ইনস্টল করা আছে।
KNOWN_CAPTURING , UNKNOWN_CAPTURING
আপনার অ্যাপ চলাকালীন স্ক্রীন দেখার জন্য ব্যবহার করা যেতে পারে এমন অনুমতিগুলি সক্রিয় আছে এমন অ্যাপগুলি চলছে৷ এটি ডিভাইসে চলমান Google Play-এর কাছে পরিচিত যেকোন যাচাইকৃত অ্যাক্সেসিবিলিটি পরিষেবাগুলিকে বাদ দেয়৷
KNOWN_CONTROLLING , UNKNOWN_CONTROLLING
এমন অ্যাপ চালু আছে যেগুলির অনুমতিগুলি সক্রিয় রয়েছে যা ডিভাইস নিয়ন্ত্রণ করতে এবং সরাসরি আপনার অ্যাপে ইনপুট নিয়ন্ত্রণ করতে ব্যবহার করা যেতে পারে এবং আপনার অ্যাপের ইনপুট এবং আউটপুট ক্যাপচার করতে ব্যবহার করা যেতে পারে। এটি ডিভাইসে চলমান Google Play-এর কাছে পরিচিত যেকোন যাচাইকৃত অ্যাক্সেসিবিলিটি পরিষেবাগুলিকে বাদ দেয়৷
KNOWN_OVERLAYS , UNKNOWN_OVERLAYS
আপনার অ্যাপে ওভারলে প্রদর্শনের জন্য ব্যবহার করা যেতে পারে এমন অনুমতিগুলি সক্রিয় আছে এমন অ্যাপগুলি চলছে৷ এটি ডিভাইসে চলমান Google Play-এর কাছে পরিচিত যেকোন যাচাইকৃত অ্যাক্সেসিবিলিটি পরিষেবাগুলিকে বাদ দেয়৷
খালি (একটি ফাঁকা মান)

একটি প্রয়োজনীয় প্রয়োজনীয়তা মিস হলে অ্যাপ অ্যাক্সেস ঝুঁকি মূল্যায়ন করা হয় না। এই ক্ষেত্রে appAccessRiskVerdict ক্ষেত্রটি খালি। এটি নিম্নলিখিত সহ বিভিন্ন কারণে ঘটতে পারে:

  • ডিভাইসটি যথেষ্ট বিশ্বাসযোগ্য নয়।
  • ডিভাইস ফর্ম ফ্যাক্টর একটি ফোন, ট্যাবলেট, বা ভাঁজযোগ্য নয়।
  • ডিভাইসটি Android 6 (API লেভেল 23) বা উচ্চতর চলমান নয়।
  • ডিভাইসে ইনস্টল করা আপনার অ্যাপের সংস্করণ Google Play-এর কাছে অজানা।
  • ডিভাইসটিতে গুগল প্লে স্টোরের সংস্করণটি পুরানো।
  • শুধুমাত্র গেমস : ব্যবহারকারীর অ্যাকাউন্টের গেমের জন্য প্লে লাইসেন্স নেই।
  • verdictOptOut প্যারামিটারের সাথে একটি আদর্শ অনুরোধ ব্যবহার করা হয়েছে।
  • একটি প্লে ইন্টিগ্রিটি এপিআই লাইব্রেরি সংস্করণের সাথে একটি আদর্শ অনুরোধ ব্যবহার করা হয়েছিল যা এখনও মানক অনুরোধগুলির জন্য অ্যাপ অ্যাক্সেস ঝুঁকি সমর্থন করে না।

অ্যাপ অ্যাক্সেস ঝুঁকি স্বয়ংক্রিয়ভাবে যাচাইকৃত অ্যাক্সেসিবিলিটি পরিষেবাগুলিকে বাদ দেয় যেগুলি একটি বর্ধিত Google Play অ্যাক্সেসিবিলিটি পর্যালোচনার মাধ্যমে করা হয়েছে (ডিভাইসের যেকোনো অ্যাপ স্টোর দ্বারা ইনস্টল করা হয়েছে)। "বাদ দেওয়া" এর অর্থ হল ডিভাইসে চলমান যাচাইকৃত অ্যাক্সেসিবিলিটি পরিষেবাগুলি অ্যাপ অ্যাক্সেসের ঝুঁকির রায়ে ক্যাপচারিং, নিয়ন্ত্রণ বা ওভারলে প্রতিক্রিয়া প্রদান করবে না। আপনার অ্যাক্সেসিবিলিটি অ্যাপ্লিকেশানের জন্য একটি বর্ধিত Google Play অ্যাক্সেসিবিলিটি পর্যালোচনার অনুরোধ করতে, আপনার অ্যাপ্লিকেশানের ম্যানিফেস্টে isAccessibilityTool পতাকা সেট করা আছে কিনা তা নিশ্চিত করে এটিকে Google Play-এ প্রকাশ করুন বা একটি পর্যালোচনার অনুরোধ করুন

নিম্নলিখিত সারণী রায়ের কিছু উদাহরণ দেয় এবং সেগুলি কী বোঝায় (এই টেবিলটি প্রতিটি সম্ভাব্য ফলাফল তালিকাভুক্ত করে না):

উদাহরণ অ্যাপ অ্যাক্সেস ঝুঁকি রায় প্রতিক্রিয়া ব্যাখ্যা
appsDetected:
["KNOWN_INSTALLED"]
শুধুমাত্র এমন অ্যাপ ইনস্টল করা আছে যেগুলি Google Play দ্বারা স্বীকৃত বা ডিভাইস নির্মাতার দ্বারা সিস্টেম পার্টিশনে প্রিলোড করা হয়েছে।
এমন কোনো অ্যাপ চলছে না যার ফলে ক্যাপচারিং, নিয়ন্ত্রণ বা ওভারলে রায় হবে।
appsDetected:
["KNOWN_INSTALLED",
"UNKNOWN_INSTALLED",
"UNKNOWN_CAPTURING"]
ডিভাইস নির্মাতার দ্বারা সিস্টেম পার্টিশনে Google Play দ্বারা ইনস্টল করা বা প্রিলোড করা অ্যাপ রয়েছে৷
অন্যান্য অ্যাপ চালু আছে এবং অনুমতিগুলি সক্ষম করা আছে যা স্ক্রীন দেখতে বা অন্যান্য ইনপুট এবং আউটপুট ক্যাপচার করতে ব্যবহার করা যেতে পারে।
appsDetected:
["KNOWN_INSTALLED",
"KNOWN_CAPTURING",
"UNKNOWN_INSTALLED",
"UNKNOWN_CONTROLLING"]
এমন প্লে বা সিস্টেম চালু আছে যেগুলির অনুমতিগুলি সক্রিয় রয়েছে যা স্ক্রীন দেখতে বা অন্যান্য ইনপুট এবং আউটপুটগুলি ক্যাপচার করতে ব্যবহার করা যেতে পারে৷
এছাড়াও অন্যান্য অ্যাপ্লিকেশানগুলি চলমান রয়েছে যেগুলির অনুমতিগুলি সক্রিয় রয়েছে যা ডিভাইস নিয়ন্ত্রণ করতে এবং সরাসরি আপনার অ্যাপে ইনপুটগুলি নিয়ন্ত্রণ করতে ব্যবহার করা যেতে পারে৷
appAccessRiskVerdict: {} অ্যাপ অ্যাক্সেস ঝুঁকি মূল্যায়ন করা হয় না কারণ একটি প্রয়োজনীয় প্রয়োজনীয়তা মিস করা হয়েছে। উদাহরণস্বরূপ, ডিভাইসটি যথেষ্ট বিশ্বাসযোগ্য ছিল না।

আপনার ঝুঁকির স্তরের উপর নির্ভর করে, আপনি সিদ্ধান্ত নিতে পারেন যে কোন রায়গুলির সমন্বয় এগিয়ে যাওয়ার জন্য গ্রহণযোগ্য এবং কোন রায়গুলির উপর আপনি পদক্ষেপ নিতে চান৷ নিচের কোড স্নিপেটটি স্ক্রীন ক্যাপচার করতে বা আপনার অ্যাপকে নিয়ন্ত্রণ করতে পারে এমন কোনো অ্যাপ চলমান নেই তা যাচাই করার একটি উদাহরণ তুলে ধরে:

কোটলিন

val environmentDetails =
    JSONObject(payload).getJSONObject("environmentDetails")
val appAccessRiskVerdict =
    environmentDetails.getJSONObject("appAccessRiskVerdict")

if (appAccessRiskVerdict.has("appsDetected")) {
    val appsDetected = appAccessRiskVerdict.getJSONArray("appsDetected").toString()
    if (!appsDetected.contains("CAPTURING") && !appsDetected.contains("CONTROLLING")) {
        // Looks good!
    }
}

জাভা

JSONObject environmentDetails =
    new JSONObject(payload).getJSONObject("environmentDetails");
JSONObject appAccessRiskVerdict =
    environmentDetails.getJSONObject("appAccessRiskVerdict");

if (appAccessRiskVerdict.has("appsDetected")) {
    String appsDetected = appAccessRiskVerdict.getJSONArray("appsDetected").toString()
    if (!appsDetected.contains("CAPTURING") && !appsDetected.contains("CONTROLLING")) {
        // Looks good!
    }
}
অ্যাপ অ্যাক্সেস ঝুঁকি রায় প্রতিকার

আপনার ঝুঁকির স্তরের উপর নির্ভর করে, ব্যবহারকারীকে একটি অনুরোধ বা পদক্ষেপ সম্পূর্ণ করতে দেওয়ার আগে আপনি কোন অ্যাপ অ্যাক্সেস ঝুঁকির রায়ের বিষয়ে পদক্ষেপ নিতে চান তা নির্ধারণ করতে পারেন। ঐচ্ছিক Google Play প্রম্পট রয়েছে যা আপনি অ্যাপ অ্যাক্সেসের ঝুঁকি যাচাই করার পরে ব্যবহারকারীকে দেখাতে পারেন। আপনি CLOSE_UNKNOWN_ACCESS_RISK দেখাতে পারেন যাতে ব্যবহারকারীকে অজানা অ্যাপগুলি বন্ধ করতে বলে যা অ্যাপ অ্যাক্সেসের ঝুঁকির রায় দেয় অথবা আপনি CLOSE_ALL_ACCESS_RISK দেখাতে পারেন যাতে ব্যবহারকারীকে সমস্ত অ্যাপ (জানা এবং অজানা) বন্ধ করতে বলে যা অ্যাপ অ্যাক্সেসের ঝুঁকির রায় দেয়।

প্লে প্রোটেক্ট রায়

একবার চালু হয়ে গেলে, Play Integrity API পেলোডে environmentDetails ক্ষেত্রটিতে Play Protect রায় থাকবে:

environmentDetails: {
  playProtectVerdict: "NO_ISSUES"
}

playProtectVerdict নিম্নলিখিত মানগুলির মধ্যে একটি থাকতে পারে:

NO_ISSUES
Play Protect চালু আছে এবং ডিভাইসে কোনো অ্যাপ সমস্যা খুঁজে পায়নি।
NO_DATA
Play Protect চালু আছে কিন্তু এখনও কোনো স্ক্যান করা হয়নি। ডিভাইস বা প্লে স্টোর অ্যাপটি হয়তো সম্প্রতি রিসেট করা হয়েছে।
POSSIBLE_RISK
Play Protect বন্ধ করা আছে।
MEDIUM_RISK
Play Protect চালু আছে এবং ডিভাইসে সম্ভাব্য ক্ষতিকারক অ্যাপ ইনস্টল করা আছে।
HIGH_RISK
Play Protect চালু আছে এবং ডিভাইসে বিপজ্জনক অ্যাপ ইনস্টল করা আছে।
UNEVALUATED

Play Protect রায়ের মূল্যায়ন করা হয়নি।

এটি নিম্নলিখিত সহ বিভিন্ন কারণে ঘটতে পারে:

  • ডিভাইসটি যথেষ্ট বিশ্বাসযোগ্য নয়।
  • শুধুমাত্র গেমস : ব্যবহারকারীর অ্যাকাউন্টের গেমের জন্য প্লে লাইসেন্স নেই।

Play Protect ব্যবহার করার বিষয়ে নির্দেশিকা

আপনার অ্যাপ্লিকেশানের ব্যাকএন্ড সার্ভার আপনার ঝুঁকি সহনশীলতার উপর ভিত্তি করে রায়ের উপর ভিত্তি করে কীভাবে কাজ করবে তা সিদ্ধান্ত নিতে পারে। এখানে কিছু পরামর্শ এবং সম্ভাব্য ব্যবহারকারীর পদক্ষেপ রয়েছে:

NO_ISSUES
Play Protect চালু আছে এবং কোনো সমস্যা খুঁজে পায়নি তাই ব্যবহারকারীর কোনো পদক্ষেপের প্রয়োজন নেই।
POSSIBLE_RISK এবং NO_DATA
এই রায়গুলি পাওয়ার সময়, ব্যবহারকারীকে Play Protect চালু আছে এবং একটি স্ক্যান করা হয়েছে তা পরীক্ষা করতে বলুন। NO_DATA শুধুমাত্র বিরল পরিস্থিতিতে উপস্থিত হওয়া উচিত৷
MEDIUM_RISK এবং HIGH_RISK
আপনার ঝুঁকি সহনশীলতার উপর নির্ভর করে, আপনি ব্যবহারকারীকে Play Protect চালু করতে এবং Play Protect সতর্কতার বিষয়ে পদক্ষেপ নিতে বলতে পারেন। ব্যবহারকারী যদি এই প্রয়োজনীয়তাগুলি পূরণ করতে না পারে তবে আপনি তাদের সার্ভার অ্যাকশন থেকে ব্লক করতে পারেন।