Uygulamanızın kendi bünyesinde barındırılan arka uçlar gibi Firebase dışı kaynaklarını koruyabilirsiniz. kullanıma sunduk. Bunun için aşağıdakilerin ikisini de yapmanız gerekir:
- Uygulama istemcinizi her istekle birlikte bir Uygulama Kontrolü jetonu gönderecek şekilde değiştirme ilgili sayfalarda açıklandığı gibi, arka ucunuza iOS+, Android ve web
- Arka ucunuzu her istekte geçerli bir uygulama kontrolü jetonu gerektirecek şekilde değiştirin. bu sayfada açıklandığı gibidir.
Jeton doğrulama
Arka ucunuzdaki Uygulama Kontrolü jetonlarını doğrulamak için API uç noktalarınıza mantık ekleyin şunları yapar:
Her isteğin bir Uygulama Kontrolü jetonu içerdiğinden emin olun.
Admin SDK'yı kullanarak Uygulama Kontrolü jetonunu doğrulayın.
Doğrulama başarılı olursa Yönetici SDK'sı kodu çözülmüş Uygulama Kontrolü'nü döndürür jeton. Doğrulama başarılı olursa jetonun kaynağı bir uygulamadır Firebase projenize ait.
İki denetimden de geçemeyen istekleri reddedin. Örneğin:
Node.js
Henüz Node.js Admin SDK'sını yüklemediyseniz lütfen unutmayın.
Ardından, örnek olarak Express.js ara katman yazılımını kullanarak:
import express from "express";
import { initializeApp } from "firebase-admin/app";
import { getAppCheck } from "firebase-admin/app-check";
const expressApp = express();
const firebaseApp = initializeApp();
const appCheckVerification = async (req, res, next) => {
const appCheckToken = req.header("X-Firebase-AppCheck");
if (!appCheckToken) {
res.status(401);
return next("Unauthorized");
}
try {
const appCheckClaims = await getAppCheck().verifyToken(appCheckToken);
// If verifyToken() succeeds, continue with the next middleware
// function in the stack.
return next();
} catch (err) {
res.status(401);
return next("Unauthorized");
}
}
expressApp.get("/yourApiEndpoint", [appCheckVerification], (req, res) => {
// Handle request.
});
Python
Henüz Python Admin SDK'sını yüklemediyseniz lütfen unutmayın.
Ardından API uç nokta işleyicilerinizde app_check.verify_token()
komutunu çağırın ve
isteği reddeder. Aşağıdaki örnekte,
@before_request
ile süslenmiş, tüm istekler için bu görevi gerçekleştirir:
import firebase_admin
from firebase_admin import app_check
import flask
import jwt
firebase_app = firebase_admin.initialize_app()
flask_app = flask.Flask(__name__)
@flask_app.before_request
def verify_app_check() -> None:
app_check_token = flask.request.headers.get("X-Firebase-AppCheck", default="")
try:
app_check_claims = app_check.verify_token(app_check_token)
# If verify_token() succeeds, okay to continue to route handler.
except (ValueError, jwt.exceptions.DecodeError):
flask.abort(401)
@flask_app.route("/yourApiEndpoint")
def your_api_endpoint(request: flask.Request):
# Handle request.
...
Go
Go için Admin SDK'yı henüz yüklemediyseniz lütfen unutmayın.
Ardından, API uç nokta işleyicilerinizde appcheck.Client.VerifyToken()
komutunu çağırın
ve başarısız olursa isteği reddeder. Aşağıdaki örnekte sarmalayıcı,
işlevi, şu mantığı uç nokta işleyicilere ekler:
package main
import (
"context"
"log"
"net/http"
firebaseAdmin "firebase.google.com/go/v4"
"firebase.google.com/go/v4/appcheck"
)
var (
appCheck *appcheck.Client
)
func main() {
app, err := firebaseAdmin.NewApp(context.Background(), nil)
if err != nil {
log.Fatalf("error initializing app: %v\n", err)
}
appCheck, err = app.AppCheck(context.Background())
if err != nil {
log.Fatalf("error initializing app: %v\n", err)
}
http.HandleFunc("/yourApiEndpoint", requireAppCheck(yourApiEndpointHandler))
log.Fatal(http.ListenAndServe(":8080", nil))
}
func requireAppCheck(handler func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) {
wrappedHandler := func(w http.ResponseWriter, r *http.Request) {
appCheckToken, ok := r.Header[http.CanonicalHeaderKey("X-Firebase-AppCheck")]
if !ok {
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte("Unauthorized."))
return
}
_, err := appCheck.VerifyToken(appCheckToken[0])
if err != nil {
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte("Unauthorized."))
return
}
// If VerifyToken() succeeds, continue with the provided handler.
handler(w, r)
}
return wrappedHandler
}
func yourApiEndpointHandler(w http.ResponseWriter, r *http.Request) {
// Handle request.
}
Diğer
Arka ucunuz başka bir dilde yazılmışsa arka ucunuz başka bir dilde yazılmışsa şurada bulunan gibi genel amaçlı bir JWT kütüphanesi: jwt.io: Uygulama Kontrolü jetonlarını doğrulamak için kullanılır.
Jeton doğrulama mantığınız aşağıdaki adımları tamamlamalıdır:
- Uygulamadan Firebase Uygulama Kontrolü'nün herkese açık JSON Web Anahtarı (JWK) Setini edinme
JWKS uç noktasını kontrol edin:
https://firebaseappcheck.googleapis.com/v1/jwks
. - Geçerli olduğundan emin olmak için Uygulama Kontrolü jetonunun imzasını doğrulayın.
- Jeton başlığının RS256 algoritmasını kullandığından emin olun.
- Jetonun başlığının JWT türünde olduğundan emin olun.
- Jetonun belirler.
- Jetonun süresinin dolmadığından emin olun.
- Jetonun kitlesinin projenizle eşleştiğinden emin olun.
- İsteğe bağlı: Jetonun konusunun, uygulamanızın uygulama kimliğiyle eşleştiğinden emin olun.
JWT kitaplıklarının özellikleri farklılık gösterebilir; manuel olarak tamamladığınızdan seçtiğiniz kitaplık tarafından işlenmeyen tüm adımlar.
Aşağıdaki örnek, jwt
kullanarak Ruby'de gerekli adımları gerçekleştirir
bir Rack ara katman yazılımı katmanı olarak kullanabilirsiniz.
require 'json'
require 'jwt'
require 'net/http'
require 'uri'
class AppCheckVerification
def initialize(app, options = {})
@app = app
@project_number = options[:project_number]
end
def call(env)
app_id = verify(env['HTTP_X_FIREBASE_APPCHECK'])
return [401, { 'Content-Type' => 'text/plain' }, ['Unauthenticated']] unless app_id
env['firebase.app'] = app_id
@app.call(env)
end
def verify(token)
return unless token
# 1. Obtain the Firebase App Check Public Keys
# Note: It is not recommended to hard code these keys as they rotate,
# but you should cache them for up to 6 hours.
uri = URI('https://firebaseappcheck.googleapis.com/v1/jwks')
jwks = JSON(Net::HTTP.get(uri))
# 2. Verify the signature on the App Check token
payload, header = JWT.decode(token, nil, true, jwks: jwks, algorithms: 'RS256')
# 3. Ensure the token's header uses the algorithm RS256
return unless header['alg'] == 'RS256'
# 4. Ensure the token's header has type JWT
return unless header['typ'] == 'JWT'
# 5. Ensure the token is issued by App Check
return unless payload['iss'] == "https://firebaseappcheck.googleapis.com/#{@project_number}"
# 6. Ensure the token is not expired
return unless payload['exp'] > Time.new.to_i
# 7. Ensure the token's audience matches your project
return unless payload['aud'].include? "projects/#{@project_number}"
# 8. The token's subject will be the app ID, you may optionally filter against
# an allow list
payload['sub']
rescue
end
end
class Application
def call(env)
[200, { 'Content-Type' => 'text/plain' }, ["Hello app #{env['firebase.app']}"]]
end
end
use AppCheckVerification, project_number: 1234567890
run Application.new
Tekrar oynatma koruması (beta)
Bir uç noktayı tekrar saldırılarından korumak için Uygulama Kontrolü jetonunu kullanabilirsiniz kullanılabilmesi için doğrulama işleminden sonra kullanılabilmesidir.
Tekrar oynatma korumasını kullanmak, verifyToken()
cihazına gidiş dönüş ağ ekler
çağrısı yapar ve bu nedenle, bu çağrıyı kullanan tüm uç noktalara gecikme ekler. İşte bu nedenle
tekrar oynatma korumasını yalnızca özellikle hassas olan
uç noktalar.
Tekrar oynatma korumasını kullanmak için aşağıdakileri yapın:
Cloud Console, "Firebase Uygulama Kontrol Jetonu Doğrulayıcı"yı verin rolünü etkinleştirmelisiniz. jetonları doğrulamak için kullanılır.
- Yönetici SDK'sını Yönetici SDK'sı hizmet hesabıyla başlattıysanız Firebase konsolundan indirdiğiniz kimlik bilgilerini kullanıyorsanız, gereken rol: zaten verildi.
- 1. nesil Cloud Functions'ı varsayılan Yönetici ayarıyla kullanıyorsanız SDK yapılandırması, rolü App Engine varsayılan hizmetine verin hesap. Hizmet hesabı izinlerini değiştirme başlıklı makaleyi inceleyin.
- Varsayılan Yönetici ayarıyla 2. nesil Cloud Functions'ı kullanıyorsanız SDK yapılandırması, rolü Varsayılan bilgi işlem hizmeti hesap.
Ardından, bir jetonu kullanmak için
{ consume: true }
öğesiniverifyToken()
öğesine iletin yöntemini kullanın ve sonuç nesnesini inceleyin;alreadyConsumed
özelliğitrue
, isteği reddedin veya bir tür düzeltici eylemde bulunun. Örneğin, arayan kişinin diğer kontrolleri geçmesini istemek.Örneğin:
const appCheckClaims = await getAppCheck().verifyToken(appCheckToken, { consume: true }); if (appCheckClaims.alreadyConsumed) { res.status(401); return next('Unauthorized'); } // If verifyToken() succeeds and alreadyConsumed is not set, okay to continue.
Bu işlem, jetonu doğrular ve ardından kullanıldı olarak işaretler. Gelecekteki çağrılar %50'si aynı jeton üzerinde
verifyToken(appCheckToken, { consume: true })
alreadyConsumed
öğesinitrue
olarak ayarla. (verifyToken()
işlevinin tüketilen bir jetonu reddetmediğini ve hattaconsume
ayarlanmazsa kullanılır.)
Bu özelliği belirli bir uç nokta için etkinleştirdiğinizde ayrıca uç nokta. Aşağıdakilerle ilgili istemci taraflı dokümanlara bakın: Apple platformları Android ve web