如何使用JWT for Google Firebase生成身份验证令牌?
所以我试图authenticate the Firebase REST API. 我使用Vapor framework服务器端快速和我安装JWT package。如何使用JWT for Google Firebase生成身份验证令牌?
我正在尝试使用serviceAccountKey.json
文件和JWT中的数据生成身份验证令牌。
这里是我试过的代码:
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": ""
}
如果你只是想要得到的东西的工作,最好不要使用1.5.0版本
.Package(url: "https://github.com/gtchance/FirebaseSwift.git", Version(1,5,0)),
并使用遗留的秘密。项目设置>服务帐户>数据库秘密
这就是我目前所做的。不知道是否应该将此标记为“解决方案”,因为原始问题仍然存在。 – rmaes4
此时我正在使用Xcode 8.3.3。 Package.swift包含:
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",
]
)
如果你生成你需要记住具备以下,从https://cloud.google.com/storage/docs/authentication
采取了服务帐户凭据:您可以通过创建一个OAuth用户端ID在云中创建平台控制台私钥一个服务帐户。您可以使用JSON和PKCS12格式获取私钥:
如果您在Google云端平台之外的生产环境中使用Application Default Credentials,则需要JSON密钥。 JSON密钥不能转换为其他格式。 PKCS12(.p12)受许多不同编程语言和库支持。如果需要,您可以使用OpenSSL将密钥转换为其他格式(see Converting the private key to other formats)。但是,PKCS12密钥不能转换为JSON格式。
注意:您请勿需要在console.cloud.google.com上生成服务帐户。只需按照下面列出的步骤1 ... 6。
转到https://console.firebase.google.com,点击您的项目,旁边的概述点击滚轮设置,单击服务帐户,滚动到页面底部,然后点击生成新的私钥。
-
转换的第12页(a.k.a PKCS12)文件。质子交换膜(a.k.a PKCS1)使用OpenSSL
cat /path/to/xxxx-privatekey.p12 | openssl pkcs12 -nodes -nocerts -passin pass:notasecret | openssl rsa > /path/to/secret.pem
去GitHub搜索VaporJWT和Xcode中导入。它将帮助您创建一个签名的JSON Web令牌。
在这个github页面上,您将学习如何提取RSA使用的私钥。
转换。质子交换膜为DER
openssl rsa -in /path/to/secret.pem -outform der -out /path/to/private.der
- 转换.der来。base64
openssl base64 -in /path/to/private.der -out /path/to/Desktop/private.txt
在private.txt中,您有用base64编码的私钥,您最终可以使用它来签署JWT。然后,您可以使用签名的JWT拨打Google API电话。
``
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"
我在我的项目中添加了.package。因为看起来你已经使用了库,所以你会告诉我们为什么我在包中找到错误“import node”而不是这个模块。我也在源文件中查找文件,但没有这样的文件。 –
您还没有解释的一个问题。你有这个代码。好。它出什么问题了? – zerkms
@zerkms这只是我在生成令牌的尝试。令牌不起作用,我得到“权限被拒绝” – rmaes4
您是否检查过生成的JWT外观与您的预期完全相同? – zerkms