Join us for Firebase Summit on November 10, 2021. Tune in to learn how Firebase can help you accelerate app development, release with confidence, and scale with ease. Register

نشانه های سفارشی ایجاد کنید

Firebase به شما این امکان را می دهد تا با احراز هویت ، کاربران یا دستگاه ها را با استفاده از نشانه های وب JSON (JWTs) تأیید کنید. شما تولید این نشانه ها بر روی سرور خود، آنها را منتقل به یک دستگاه مشتری، و سپس استفاده از آنها به اعتبار از طریق signInWithCustomToken() روش.

برای دستیابی به این هدف ، شما باید یک نقطه پایانی سرور ایجاد کنید که اعتبار ورود به سیستم را بپذیرد-مانند نام کاربری و رمز عبور-و اگر اعتبارنامه معتبر باشد ، یک JWT سفارشی را برمی گرداند. JWT سفارشی بازگشت از سرور خود را می تواند توسط یک دستگاه سرویس گیرنده استفاده می شود برای تأیید هویت با Firebase ( در iOS ، آندروید ، وب ). پس از احراز هویت ، این هویت هنگام دسترسی به سایر خدمات Firebase ، مانند پایگاه داده Firebase Realtime Database و Cloud Storage مورد استفاده قرار می گیرد. علاوه بر این، محتویات JWT در دسترس خواهد بود auth شی در خود بیدرنگ قوانین پایگاه و request.auth شی در خود ذخیره سازی ابر قوانین امنیتی .

اگر سرور شما به زبانی نوشته شده است که Firebase بطور طبیعی از آن پشتیبانی نمی کند ، می توانید یک توکن سفارشی با Firebase Admin SDK ایجاد کنید ، یا می توانید از یک کتابخانه JWT شخص ثالث استفاده کنید.

قبل از اینکه شروع کنی

توکن های سفارشی JWT هایی هستند که کلید خصوصی مورد استفاده برای امضای آن متعلق به یک حساب سرویس Google است. چندین روش برای تعیین حساب سرویس Google وجود دارد که باید توسط SDK سرپرست Firebase برای امضای توکن های سفارشی استفاده شود:

  • با استفاده از یک فایل JSON حساب خدمات - این روش می تواند در هر محیط استفاده می شود، اما نیاز شما را برای بسته بندی یک فایل JSON حساب خدمات همراه با کد خود را. باید مراقبت ویژه ای صورت گیرد تا اطمینان حاصل شود که فایل سرویس JSON در معرض دید خارجی قرار نمی گیرد.
  • اجازه دادن به SDK محیط مدیریت کشف یک حساب کاربری سرویس - این روش می تواند در محیط های گوگل مانند توابع و Google Cloud موتور نرم افزار مدیریت استفاده می شود. ممکن است مجبور شوید برخی مجوزهای اضافی را از طریق Google Cloud Console پیکربندی کنید.
  • با استفاده از یک ID حساب خدمات - هنگامی که در یک محیط مدیریت شده توسط Google استفاده از این روش خواهد نشانه با استفاده از کلید اعتبار خدمات مشخص ثبت نام. با این حال ، از سرویس وب از راه دور استفاده می کند و ممکن است مجبور شوید مجوزهای بیشتری را برای این حساب سرویس از طریق Google Cloud Console پیکربندی کنید.

استفاده از یک فایل سرویس JSON

پرونده های سرویس JSON شامل کلیه اطلاعات مربوط به حسابهای سرویس (از جمله کلید خصوصی RSA) است. آنها را می توان از کنسول Firebase بارگیری کرد. دنبال SDK محیط مدیریت راه اندازی دستورالعمل برای اطلاعات بیشتر در مورد نحوه مقداردهی اولیه SDK مدیریت با یک فایل JSON حساب خدمات.

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

اجازه می دهد SDK سرپرست یک حساب خدمات را کشف کند

اگر کد شما در محیطی اداره می شود که توسط Google مدیریت می شود ، SDK سرپرست می تواند راهی را برای امضای نشانه های سفارشی کشف کند:

  • اگر کد خود را در محیط برنامه استاندارد موتور برای جاوا، پایتون یا برو مستقر شده، از SDK محیط مدیریت می توانید با استفاده از خدمات برنامه هویت در حال حاضر در آن محیط به ثبت نام نشانه های سفارشی. سرویس App Identity داده ها را با استفاده از حساب سرویس ارائه شده توسط Google App Engine برای برنامه شما امضا می کند.

  • اگر کد خود را در برخی از محیط زیست دیگر موفق (به عنوان مثال توابع گوگل ابر موتور محاسباتی) مستقر شده، می تواند فایربیس محیط مدیریت SDK خودکار کشف یک رشته از شناسه حساب خدمات از محلی سرور ابرداده . سپس شناسه حساب سرویس کشف شده همراه با سرویس IAM برای امضای نشانه ها از راه دور استفاده می شود.

برای استفاده از این روش های امضاء ، SDK را با اعتبارنامه Google Application Default تنظیم کنید و رشته شناسه حساب سرویس را مشخص نکنید:

Node.js

initializeApp();

جاوا

FirebaseApp.initializeApp();

پایتون

default_app = firebase_admin.initialize_app()

برو

app, err := firebase.NewApp(context.Background(), nil)
if err != nil {
	log.Fatalf("error initializing app: %v\n", err)
}

سی شارپ

FirebaseApp.Create();

برای تست همان کد به صورت محلی، دانلود یک فایل JSON حساب خدمات و مجموعه ای از GOOGLE_APPLICATION_CREDENTIALS متغیر محیطی به نقطه به آن است.

اگر SDK سرپرست Firebase باید یک رشته شناسه حساب سرویس را کشف کند ، این کار را هنگامی انجام می دهد که کد شما برای اولین بار یک توکن سفارشی ایجاد می کند. نتیجه ذخیره می شود و مجدداً برای عملیات امضای توکن بعدی استفاده می شود. شناسه حساب سرویس کشف شده معمولاً یکی از حسابهای سرویس پیش فرض ارائه شده توسط Google Cloud است:

درست مانند خدمات صراحت مشخص شناسه حساب، خودرو خدمات کشف شناسه حساب باید داشته iam.serviceAccounts.signBlob اجازه سفارشی ایجاد رمز به کار می کنند. شما ممکن است به استفاده از IAM و مدیریت بخش از ابر کنسول گوگل برای اعطای خدمات به طور پیش فرض به حساب مجوزهای لازم. برای جزئیات بیشتر به بخش عیب یابی زیر مراجعه کنید.

استفاده از شناسه حساب سرویس

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

شناسه حساب خدمات را می توان در یافت ابر کنسول گوگل ، و یا در client_email زمینه خدمات دانلود فایل حساب JSON. خدمات شناسه حساب ایمیل های با فرمت زیر را داشته باشد: <client-id>@<project-id>.iam.gserviceaccount.com . آنها به طور منحصر به فرد حساب های خدمات را در پروژه های Firebase و Google Cloud شناسایی می کنند.

برای ایجاد توکن های سفارشی با استفاده از شناسه حساب سرویس جداگانه ، SDK را مانند تصویر زیر راه اندازی کنید:

Node.js

initializeApp({
  serviceAccountId: 'my-client-id@my-project-id.iam.gserviceaccount.com',
});

جاوا

FirebaseOptions options = FirebaseOptions.builder()
    .setCredentials(GoogleCredentials.getApplicationDefault())
    .setServiceAccountId("my-client-id@my-project-id.iam.gserviceaccount.com")
    .build();
FirebaseApp.initializeApp(options);

پایتون

options = {
    'serviceAccountId': 'my-client-id@my-project-id.iam.gserviceaccount.com',
}
firebase_admin.initialize_app(options=options)

برو

conf := &firebase.Config{
	ServiceAccountID: "my-client-id@my-project-id.iam.gserviceaccount.com",
}
app, err := firebase.NewApp(context.Background(), conf)
if err != nil {
	log.Fatalf("error initializing app: %v\n", err)
}

سی شارپ

FirebaseApp.Create(new AppOptions()
{
    Credential = GoogleCredential.GetApplicationDefault(),
    ServiceAccountId = "my-client-id@my-project-id.iam.gserviceaccount.com",
});

شناسه های حساب خدمات اطلاعات حساسی نیستند و بنابراین قرار گرفتن در معرض آنها بی اهمیت است. با این حال ، برای امضای توکن های سفارشی با حساب سرویس مشخص شده ، SDK سرپرست Firebase باید یک سرویس از راه دور را فراخوانی کند. علاوه بر این، شما همچنین باید مطمئن شوید که را که حساب خدمات SDK محیط مدیریت است با استفاده از این تماس را به -usually {project-name}@appspot.gserviceaccount.com - دارای iam.serviceAccounts.signBlob اجازه . برای جزئیات بیشتر به بخش عیب یابی زیر مراجعه کنید.

با استفاده از SDK مدیریت Firebase ، توکن های سفارشی ایجاد کنید

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

Node.js

const uid = 'some-uid';

getAuth()
  .createCustomToken(uid)
  .then((customToken) => {
    // Send token back to client
  })
  .catch((error) => {
    console.log('Error creating custom token:', error);
  });

جاوا

String uid = "some-uid";

String customToken = FirebaseAuth.getInstance().createCustomToken(uid);
// Send token back to client

پایتون

uid = 'some-uid'

custom_token = auth.create_custom_token(uid)

برو

client, err := app.Auth(context.Background())
if err != nil {
	log.Fatalf("error getting Auth client: %v\n", err)
}

token, err := client.CustomToken(ctx, "some-uid")
if err != nil {
	log.Fatalf("error minting custom token: %v\n", err)
}

log.Printf("Got custom token: %v\n", token)

سی شارپ

var uid = "some-uid";

string customToken = await FirebaseAuth.DefaultInstance.CreateCustomTokenAsync(uid);
// Send token back to client

همچنین می توانید به صورت اختیاری ادعاهای دیگری را برای قرار دادن در توکن سفارشی تعیین کنید. به عنوان مثال، در زیر، یک premiumAccount درست شده است به رمز های سفارشی، که در دسترس خواهد بود اضافه auth / request.auth اشیاء در قوانین امنیت خود قرار دهید:

Node.js

const userId = 'some-uid';
const additionalClaims = {
  premiumAccount: true,
};

getAuth()
  .createCustomToken(userId, additionalClaims)
  .then((customToken) => {
    // Send token back to client
  })
  .catch((error) => {
    console.log('Error creating custom token:', error);
  });

جاوا

String uid = "some-uid";
Map<String, Object> additionalClaims = new HashMap<String, Object>();
additionalClaims.put("premiumAccount", true);

String customToken = FirebaseAuth.getInstance()
    .createCustomToken(uid, additionalClaims);
// Send token back to client

پایتون

uid = 'some-uid'
additional_claims = {
    'premiumAccount': True
}

custom_token = auth.create_custom_token(uid, additional_claims)

برو

client, err := app.Auth(context.Background())
if err != nil {
	log.Fatalf("error getting Auth client: %v\n", err)
}

claims := map[string]interface{}{
	"premiumAccount": true,
}

token, err := client.CustomTokenWithClaims(ctx, "some-uid", claims)
if err != nil {
	log.Fatalf("error minting custom token: %v\n", err)
}

log.Printf("Got custom token: %v\n", token)

سی شارپ

var uid = "some-uid";
var additionalClaims = new Dictionary<string, object>()
{
    { "premiumAccount", true },
};

string customToken = await FirebaseAuth.DefaultInstance
    .CreateCustomTokenAsync(uid, additionalClaims);
// Send token back to client

با استفاده از نشانه های سفارشی برای مشتریان وارد سیستم شوید

پس از ایجاد یک توکن سفارشی ، باید آن را به برنامه مشتری خود ارسال کنید. اعتبار میبخشد برنامه کلاینت با سفارشی نشانه با تماس signInWithCustomToken() :

iOS

هدف-ج
[[FIRAuth auth] signInWithCustomToken:customToken
                           completion:^(FIRAuthDataResult * _Nullable authResult,
                                        NSError * _Nullable error) {
  // ...
}];
سریع
Auth.auth().signIn(withCustomToken: customToken ?? "") { user, error in
  // ...
}

اندروید

mAuth.signInWithCustomToken(mCustomToken)
        .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    // Sign in success, update UI with the signed-in user's information
                    Log.d(TAG, "signInWithCustomToken:success");
                    FirebaseUser user = mAuth.getCurrentUser();
                    updateUI(user);
                } else {
                    // If sign in fails, display a message to the user.
                    Log.w(TAG, "signInWithCustomToken:failure", task.getException());
                    Toast.makeText(CustomAuthActivity.this, "Authentication failed.",
                            Toast.LENGTH_SHORT).show();
                    updateUI(null);
                }
            }
        });

وحدت

auth.SignInWithCustomTokenAsync(custom_token).ContinueWith(task => {
  if (task.IsCanceled) {
    Debug.LogError("SignInWithCustomTokenAsync was canceled.");
    return;
  }
  if (task.IsFaulted) {
    Debug.LogError("SignInWithCustomTokenAsync encountered an error: " + task.Exception);
    return;
  }

  Firebase.Auth.FirebaseUser newUser = task.Result;
  Debug.LogFormat("User signed in successfully: {0} ({1})",
      newUser.DisplayName, newUser.UserId);
});

C ++

firebase::Future<firebase::auth::User*> result =
    auth->SignInWithCustomToken(custom_token);

وب

firebase.auth().signInWithCustomToken(token)
  .then((userCredential) => {
    // Signed in
    var user = userCredential.user;
    // ...
  })
  .catch((error) => {
    var errorCode = error.code;
    var errorMessage = error.message;
    // ...
  });

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

در همان راه به عنوان با دیگر ورود به سیستم روش (مانند signInWithEmailAndPassword() و signInWithCredential() ) در auth شی در خود بیدرنگ قوانین پایگاه و request.auth شی در خود ذخیره سازی ابر قوانین امنیتی خواهد شد با کاربر جمعیت uid . در این مورد، uid خواهد بود که شما مشخص شده هنگام ایجاد رمز های سفارشی.

قوانین پایگاه داده

{
  "rules": {
    "adminContent": {
      ".read": "auth.uid === 'some-uid'"
    }
  }
}

قوانین ذخیره سازی

service firebase.storage {
  match /b/<your-firebase-storage-bucket>/o {
    match /adminContent/{filename} {
      allow read, write: if request.auth != null && request.auth.uid == "some-uid";
    }
  }
}

اگر رمز سفارشی شامل ادعاهای دیگری، آنها را می توان از اشاره auth.token (پایگاه فایربیس بیدرنگ) و یا request.auth.token (ابر ذخیره سازی) شی در قوانین خود قرار دهید:

قوانین پایگاه داده

{
  "rules": {
    "premiumContent": {
      ".read": "auth.token.premiumAccount === true"
    }
  }
}

قوانین ذخیره سازی

service firebase.storage {
  match /b/<your-firebase-storage-bucket>/o {
    match /premiumContent/{filename} {
      allow read, write: if request.auth.token.premiumAccount == true;
    }
  }
}

با استفاده از کتابخانه JWT شخص ثالث توکن های سفارشی ایجاد کنید

اگر پشتیبان شما به زبانی است که SDK رسمی Firebase Admin ندارد ، همچنان می توانید توکن های سفارشی به صورت دستی ایجاد کنید. اول، پیدا کردن یک کتابخانه JWT شخص ثالث برای زبان شما. سپس ، از آن کتابخانه JWT برای ضبط JWT که شامل ادعاهای زیر است استفاده کنید:

ادعاهای توکن سفارشی
alg الگوریتم "RS256"
iss صادرکننده آدرس ایمیل حساب پروژه پروژه شما
sub موضوع آدرس ایمیل حساب پروژه پروژه شما
aud حضار "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit"
iat صادر شده در زمان زمان کنونی ، بر حسب ثانیه از دوران یونیکس
exp زمان انقضا زمان ، در عرض چند ثانیه از دوران یونیکس ، که در آن توکن منقضی می شود. این می تواند حداکثر 3600 ثانیه بعد از iat .
توجه: این تنها کنترل زمانی که سفارشی رمز خود را منقضی می شود. اما هنگامی که شما ثبت نام کاربران در استفاده از signInWithCustomToken() ، آنها را همچنان در به دستگاه وارد سیستم تا زمانی که جلسه خود باطل است یا نشانه برای کاربران است.
uid شناسه منحصر به فرد کاربر وارد سیستم شده باید یک رشته ، بین 1 تا 36 نویسه باشد
claims (اختیاری) ادعاهای سفارشی اختیاری به در قوانین امنیت auth / request.auth متغیر

در اینجا چند نمونه از نحوه ایجاد نشانه های سفارشی به زبان های مختلف وجود دارد که SDK سرپرست Firebase از آنها پشتیبانی نمی کند:

پی اچ پی

با استفاده از php-jwt :

// Requires: composer require firebase/php-jwt
use Firebase\JWT\JWT;

// Get your service account's email address and private key from the JSON key file
$service_account_email = "abc-123@a-b-c-123.iam.gserviceaccount.com";
$private_key = "-----BEGIN PRIVATE KEY-----...";

function create_custom_token($uid, $is_premium_account) {
  global $service_account_email, $private_key;

  $now_seconds = time();
  $payload = array(
    "iss" => $service_account_email,
    "sub" => $service_account_email,
    "aud" => "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
    "iat" => $now_seconds,
    "exp" => $now_seconds+(60*60),  // Maximum expiration time is one hour
    "uid" => $uid,
    "claims" => array(
      "premium_account" => $is_premium_account
    )
  );
  return JWT::encode($payload, $private_key, "RS256");
}

یاقوت

با استفاده از ruby-jwt :

require "jwt"

# Get your service account's email address and private key from the JSON key file
$service_account_email = "service-account@my-project-abc123.iam.gserviceaccount.com"
$private_key = OpenSSL::PKey::RSA.new "-----BEGIN PRIVATE KEY-----\n..."

def create_custom_token(uid, is_premium_account)
  now_seconds = Time.now.to_i
  payload = {:iss => $service_account_email,
             :sub => $service_account_email,
             :aud => "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
             :iat => now_seconds,
             :exp => now_seconds+(60*60), # Maximum expiration time is one hour
             :uid => uid,
             :claims => {:premium_account => is_premium_account}}
  JWT.encode payload, $private_key, "RS256"
end

پس از ایجاد توکن سفارشی ، آن را به برنامه مشتری خود ارسال کنید تا از آن برای احراز هویت با Firebase استفاده کند. برای انجام این کار به نمونه کد های بالا مراجعه کنید.

عیب یابی

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

API IAM فعال نیست

اگر در حال تعیین شناسه حساب سرویس برای امضای توکن ها هستید ، ممکن است خطایی شبیه به موارد زیر دریافت کنید:

Identity and Access Management (IAM) API has not been used in project
1234567890 before or it is disabled. Enable it by visiting
https://console.developers.google.com/apis/api/iam.googleapis.com/overview?project=1234567890
then retry. If you enabled this API recently, wait a few minutes for the action
to propagate to our systems and retry.

فایربیس محیط مدیریت SDK با استفاده از API IAM به نشانه علامت. این خطا نشان می دهد که API IAM در حال حاضر برای پروژه Firebase شما فعال نیست. پیوند پیام خطا را در مرورگر وب باز کنید و روی دکمه "فعال کردن API" کلیک کنید تا در پروژه شما فعال شود.

حساب سرویس مجوزهای لازم را ندارد

اگر سرویس حساب فایربیس محیط مدیریت SDK در حال اجرا است به عنوان می کند ندارد iam.serviceAccounts.signBlob اجازه، شما ممکن است یک پیغام خطا مانند زیر دریافت کنید:

Permission iam.serviceAccounts.signBlob is required to perform this operation
on service account projects/-/serviceAccounts/{your-service-account-id}.

ساده ترین راه حل این است که به کمک مالی "حساب نشانه سرویس خالق" نقش IAM به حساب خدمات در سوال، معمولا {project-name}@appspot.gserviceaccount.com :

  1. را باز IAM و مدیریت صفحه در ابر کنسول گوگل.
  2. پروژه خود را انتخاب کرده و روی "ادامه" کلیک کنید.
  3. روی نماد ویرایش مربوط به حساب سرویس موردنظر برای بروزرسانی کلیک کنید.
  4. روی "افزودن نقش دیگر" کلیک کنید.
  5. در فیلتر جستجو "Service Account Token Creator" را وارد کنید و آن را از نتایج انتخاب کنید.
  6. برای تأیید اعطای نقش ، روی "ذخیره" کلیک کنید.

برای اشاره مستندات IAM برای جزئیات بیشتر در این فرایند، یا یاد بگیرند که چگونه به انجام این کار نقش به روز رسانی با استفاده از gcloud ابزار خط فرمان.

تعیین حساب سرویس انجام نشد

در صورت دریافت پیغام خطا مشابه موارد زیر ، SDK مدیریت Firebase به درستی راه اندازی نشده است.

Failed to determine service account ID. Initialize the SDK with service account
credentials or specify a service account ID with iam.serviceAccounts.signBlob
permission.

اگر برای کشف خودکار شناسه حساب سرویس به SDK متکی هستید ، مطمئن شوید که کد در محیط مدیریت شده Google با سرور فراداده مستقر شده است. در غیر این صورت ، حتماً فایل JSON حساب سرویس یا شناسه حساب سرویس را در راه اندازی SDK مشخص کنید.