如何使用JWT for Google Firebase生成身份验证令牌? [英] How do I generate an auth token using JWT for Google firebase?

查看:320
本文介绍了如何使用JWT for Google Firebase生成身份验证令牌?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我正在尝试验证Firebase REST API。 b $ b我为服务器端swift使用 Vapor框架,我安装了 JWT包

我试图使用 serviceAccountKey.json 文件和JWT生成一个授权令牌。



下面是我试过的代码:

  let payload timeIntervalSince1970,
exp:Date()。timeIntervalSince1970 + 3600,
iss:serviceAccountKey中的client_email。 json,
aud:https://accounts.google.com/o/oauth2/token,
范围:[
https://www.googleapis .com / auth / firebase.database,
https://www.googleapis.com/auth/userinfo.email
]
])
let privateKey =复制自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:,
cl ient_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:


解决方案

这次我使用Xcode 8.3.3。 Package.swift包含:
$ b $ pre $ let $ 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 ,
本地化,
公共,
资源,
测试,
]

如果您生成服务帐户凭证,则需要记住以下内容,取自 https:/ /cloud.google.com/storage/docs/authentication :您可以通过为服务帐户创建OAuth客户端ID来在Cloud Platform Console中创建私钥。您可以使用JSON和PKCS12格式获取您的私钥:



如果您使用的是应用程序默认凭据在Google云端平台之外的生产环境中。 JSON密钥无法转换为其他格式。 PKCS12(.p12)由许多不同的编程语言和库支持。如果需要,您可以使用OpenSSL将密钥转换为其他格式(请参阅将私钥转换为其他格式)。但是,PKCS12密钥不能转换为JSON格式。

注意需要在console.cloud.google.com上生成服务帐户。只需按照下面列出的步骤1 ... 6即可。


  1. 转到 https://console.firebase.google.com ,点击您的项目,点击概览旁边的轮子设置,点击服务帐户,滚动到在页面底部点击Generate New Private Key。使用OpenSSL将p.12(aka pkcs12)文件转换为.pem(aka pkcs1)

    $ b

  2. $ b

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


  3. 转到github并搜索 VaporJWT 并将其导入到Xcode中。它将帮助您创建一个签名的JSON Web令牌。

  4. 在这个github页面上,您将学习如何提取RSA使用的私钥。

  5. 转换.pem到der

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


  6. 将.der转换为.base64

    openssl base64 -in /path/to/private.der -out /path/to/Desktop/private.txt

    在private.txt中,你有私钥编码在base64中,你可以用来签署你的JWT。然后,您可以使用签名的JWT拨打Google API电话。

``

  Vapor 
import VaporJWT

let drop = Droplet()
var tokenID:String!

//设置当前日期
let dateNow = Date()

//分配给expDate OAuth服务器返回的令牌的有效期(3600秒)
var expDate = String(int(dateNow.timeIntervalSince1970 +(60 * 60)))

//分配给iatDate调用请求访问令牌的时间$ b $ (JWT的第一部分)
let headerJWT = [alg: RS256,typ:JWT]

// JSON Web令牌的声明集
让jwtClaimSet =
[iss:firebase-adminsdk- c7i38@fir-30c9e.iam.gserviceaccount.com,
scope:https://www.googleapis.com/auth/firebase.database,
aud:https: //www.googleapis.com/oauth2/v4/token,
exp:expDate,
iat:iatDate]


// //使用VaporJWT构造一个JSON Web Token并用RS256算法签名
// Goo支持的唯一签名算法gle OAuth 2.0 Authorization
//服务器是使用SHA-256散列算法的RSA。

let jwt = try JWT(headers:Node(node:headerJWT),payload:Node(node:jwtClaimSet),编码:Base64URLEncoding(),签名者:RS256(encodedKey: ))

//创建JSON Web令牌
让JWTtoken = try jwt.createToken()
let grant_type = urn:ietf:params:oauth:grant-type:jwt-bearer//这个值一定不能改变
let unreserved =* -._
let allowed = NSMutableCharacterSet.alphanumeric()
allowed.addCharacters(in:unreserved)
$ b $ //%或URL编码grant_type
let grant_URLEncoded = grant_type.addingPercentEncoding(withAllowedCharacters:允许为CharacterSet)

//创建一个由grant_type和assertion组成的字符串。注意!!!只有grant_type的值是URL编码的。
// JSON Web令牌值不需要被URL编码
var fullString =grant_type = \(grant_URLEncoded!)&assertion = \(JWTtoken)


//在body参数中传递fullString
drop.get(call){request in


let response = try drop.client.post( https://www.googleapis.com/oauth2/v4/token,标题:[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)

返回成功


So I'm trying to authenticate the Firebase REST API. I'm using the Vapor framework for server side swift and I installed the JWT package.

I'm trying to use the data in the serviceAccountKey.json file and JWT to generate an auth token.

Here is the code I've tried:

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": ""
}

解决方案

At this time I am using Xcode 8.3.3. Package.swift contains:

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",
]
)

If you generate a service account credential you need to have in mind the following, taken from https://cloud.google.com/storage/docs/authentication : You can create a private key in the Cloud Platform Console by creating an OAuth Client ID for a service account. You can get your private key in JSON and PKCS12 format:

JSON keys are required if you are using Application Default Credentials in a production environment outside of Google Cloud Platform. JSON keys cannot be converted to other formats. PKCS12 (.p12) is supported by many different programming languages and libraries. If needed, you can convert the key into other formats using OpenSSL (see Converting the private key to other formats). However, PKCS12 keys cannot be converted to JSON format.

Note: You do NOT need to generate a service account at console.cloud.google.com . Just follow the steps 1...6 listed below.

  1. Go to https://console.firebase.google.com , click on your project, next to Overview click on the wheel Settings, click on Service Accounts, scroll to the bottom of the page and click on Generate New Private Key.

  2. Convert the p.12 (a.k.a pkcs12) file to .pem (a.k.a pkcs1) using OpenSSL

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

  3. Go to github and search VaporJWT and import it in Xcode. It will help you create a signed JSON Web Token.

  4. On this github page you will learn how to extract the private key for RSA use.

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

  6. Convert .der to .base64
    openssl base64 -in /path/to/private.der -out /path/to/Desktop/private.txt
    In private.txt you have the private key encoded in base64 which you can finally use to sign your JWT. Then you can make calls to Google API with the signed 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":"firebase-adminsdk-c7i38@fir-30c9e.iam.gserviceaccount.com",
     "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"

这篇关于如何使用JWT for Google Firebase生成身份验证令牌?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆