2017-09-25 68 views
5

Próbuję więc authenticate the Firebase REST API. używam Vapor framework dla serwera swift stronie i zainstalowałem JWT package.Jak wygenerować token uwierzytelniający za pomocą JWT dla Google firebase?

Próbuję użyć danych z pliku serviceAccountKey.json i JWT do wygenerowania tokena autoryzacji.

Oto kod próbowałem:

let payload = try JSON(node: [ 
     "iat": Date().timeIntervalSince1970, 
     "exp": Date().timeIntervalSince1970 + 3600, 
     "iss": "client_email from serviceAccountKey.json", 
     "aud": "https://accounts.google.com/o/oauth2/token", 
     "scope": [ 
      "https://www.googleapis.com/auth/firebase.database", 
      "https://www.googleapis.com/auth/userinfo.email" 
     ] 
    ]) 
    let privateKey = "copied from serviceAccountKey.json" 

    let signer = try HS256(bytes: privateKey.bytes) 

    let jwt = try JWT(payload: payload, signer: signer) 
    let token = try jwt.createToken() 
    print(token) 

serviceAccountKey.json

{ 
    "type": "service_account", 
    "project_id": "", 
    "private_key_id": "", 
    "private_key": "", 
    "client_email": "", 
    "client_id": "", 
    "auth_uri": "https://accounts.google.com/o/oauth2/auth", 
    "token_uri": "https://accounts.google.com/o/oauth2/token", 
    "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", 
    "client_x509_cert_url": "" 
} 
+0

Nie wyjaśniono problem. Masz ten kod. Dobry. Co jest z tym nie tak? – zerkms

+0

@zerkms To była tylko moja próba wygenerowania tokena. Token nie działa i otrzymuję "odmowę zgody" – rmaes4

+0

Czy sprawdziłeś, że wygenerowany JWT wygląda dokładnie tak, jak oczekujesz? – zerkms

Odpowiedz

1

Jeśli tylko chcesz dostać rzeczy działa, lepiej wyłączyć za pomocą wersji 1.5.0

.Package(url: "https://github.com/gtchance/FirebaseSwift.git", Version(1,5,0)), 

I używanie dotychczasowego sekretu. Ustawienia projektu> Konta usług> Sekrety baz danych

+0

To właśnie robię na razie. Nie jestem pewien, czy powinienem oznaczyć to jako "rozwiązanie", ponieważ pierwotny problem pozostaje. – rmaes4

2

W tym czasie używam Xcode 8.3.3. Package.swift zawiera:

let package = Package(
name: "StripePayment", 
dependencies: [ 
    .Package(url: "https://github.com/vapor/vapor.git", majorVersion: 1, minor: 5), 
    .Package(url:"https://github.com/vapor/jwt.git", majorVersion: 0,minor: 8), 
    .Package(url: "https://github.com/SwiftyJSON/SwiftyJSON.git", versions: Version(1, 0, 0)..<Version(3, .max, .max)) 

], 
exclude: [ 
    "Config", 
    "Database", 
    "Localization", 
    "Public", 
    "Resources", 
    "Tests", 
] 
) 

Jeśli wygenerować poświadczeń konta usługi trzeba mieć na uwadze następujące dane, zaczerpnięte z https://cloud.google.com/storage/docs/authentication: Można utworzyć klucz prywatny w konsoli Cloud Platform tworząc identyfikator klienta OAuth dla konto usługi. Możesz uzyskać swój klucz prywatny w formacie JSON i PKCS12:

Klucze JSON są wymagane, jeśli korzystasz z usługi Application Default Credentials w środowisku produkcyjnym poza platformą Google Cloud Platform. Klawiszy JSON nie można konwertować na inne formaty. PKCS12 (.p12) jest obsługiwany przez wiele różnych języków programowania i bibliotek. W razie potrzeby możesz przekonwertować klucz na inny format za pomocą OpenSSL (see Converting the private key to other formats). Jednak kluczy PKCS12 nie można konwertować do formatu JSON.

Uwaga: ty nie potrzebę uzyskania konta usługi w console.cloud.google.com. Wystarczy wykonać opisane poniżej kroki 1 ... 6.

  1. Idź do https://console.firebase.google.com, kliknij na projekcie, obok spisu kliknij Ustawienia kół, kliknij kont usług, przejdź na dół strony i kliknij Utwórz nowy klucz prywatny.

  2. Konwersja str.12 (a.k.a PKCS12) złożyć do .pem (a.k.a PKCS1) przy użyciu OpenSSL

    cat /path/to/xxxx-privatekey.p12 | openssl pkcs12 -nodes -nocerts -passin pass:notasecret | openssl rsa > /path/to/secret.pem

  3. idź do GitHub i szukać VaporJWT i zaimportować go w Xcode. Pomoże Ci stworzyć podpisany token internetowy JSON.

  4. Na tej stronie github dowiesz się, jak wyodrębnić klucz prywatny do używania RSA.

  5. Konwersja .pem Der
    openssl rsa -in /path/to/secret.pem -outform der -out /path/to/private.der

  6. Convert .der do.base64
    openssl base64 -in /path/to/private.der -out /path/to/Desktop/private.txt
    W private.txt masz klucz prywatny zakodowany w base64, który możesz w końcu użyć do podpisania JWT. Następnie możesz nawiązywać połączenia z Google API z podpisanym JWT.

`

import Vapor 
import VaporJWT 

let drop = Droplet() 
var tokenID:String! 

//set current date 
let dateNow = Date() 

// assign to expDate the validity period of the token returned by OAuth server (3600 seconds) 
var expDate = String(Int(dateNow.timeIntervalSince1970 + (60 * 60))) 

// assign to iatDate the time when the call was made to request an access token 
var iatDate = String(Int(dateNow.timeIntervalSince1970)) 

// the header of the JSON Web Token (first part of the JWT) 
let headerJWT = ["alg":"RS256","typ":"JWT"] 

// the claim set of the JSON Web Token 
let jwtClaimSet = 
    ["iss":"[email protected]", 
    "scope":"https://www.googleapis.com/auth/firebase.database", 
    "aud":"https://www.googleapis.com/oauth2/v4/token", 
    "exp": expDate, 
    "iat": iatDate] 


//Using VaporJWT construct a JSON Web Token and sign it with RS256 algorithm 
//The only signing algorithm supported by the Google OAuth 2.0 Authorization  
//Server is RSA using SHA-256 hashing algorithm. 

    let jwt = try JWT(headers: Node(node: headerJWT), payload: Node(node:jwtClaimSet), encoding: Base64URLEncoding(), signer: RS256(encodedKey: "copy paste here what you have in private.txt as explained at point 7 above ")) 

// create the JSON Web Token 
    let JWTtoken = try jwt.createToken() 
let grant_type = "urn:ietf:params:oauth:grant-type:jwt-bearer" // this value must not be changed 
    let unreserved = "*-._" 
    let allowed = NSMutableCharacterSet.alphanumeric() 
    allowed.addCharacters(in: unreserved) 

// percent or URL encode grant_type 
let grant_URLEncoded = grant_type.addingPercentEncoding(withAllowedCharacters: allowed as CharacterSet) 

// create a string made of grant_type and assertion. NOTE!!! only grant_type's value is URL encoded. 
//JSON Web Token value does not need to be URL encoded 
    var fullString = "grant_type=\(grant_URLEncoded!)&assertion=\(JWTtoken)" 


    //pass fullString in the body parameter 
    drop.get("call") { request in 


    let response = try drop.client.post("https://www.googleapis.com/oauth2/v4/token", headers: ["Content-Type": "application/x-www-form-urlencoded"], query: [:],body: fullString) 

    let serverResp = response.headers 
    let serverBody = response.body.bytes 
     let serverJson = try JSON(bytes: serverBody!) 
     print(serverJson) 

    return "Success" 
+0

Dodałem pakiet .package do mojego projektu. Jak się wydaje, korzystałeś z biblioteki, więc możesz nam powiedzieć, dlaczego otrzymuję błąd "importuj węzeł", a nie taki moduł w pakiecie. Również szukałem pliku w źródle, ale nie ma takiego pliku. –