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 create service account credentials, you need to keep 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 the account service records. You can get your private key in JSON and PKCS12 format:
JSON keys are required if you use Application Default Credentials in a production environment outside of the Google cloud platform. JSON keys cannot be converted to other formats . PKCS12 (.p12) is supported by many programming languages and libraries. If necessary, you can convert the key to other formats using OpenSSL ( see Section Converting a Private Key to Other Formats ). However, PKCS12 keys cannot be converted to JSON format.
Note You do NOT have to create a service account at console.cloud.google.com. Just follow steps 1 ... 6 listed below.
Go to https://console.firebase.google.com , click on your project, next to Browse click on the Settings wheel, click on “Service Accounts”, highlight the bottom of the page and click on “Create a new private key”.
Convert p.12 (aka pkcs12) file to .pem (aka pkcs1) using OpenSSL
cat /path/to/xxxx-privatekey.p12 | openssl pkcs12 -nodes -nocerts -passin pass:notasecret | openssl rsa > /path/to/secret.pem
Go to github and search for VaporJWT and import it into Xcode. This will help you create a signed JSON Web Token.
On this github page, you'll learn how to extract the private key to use RSA.
Convert .pem to der
openssl rsa -in /path/to/secret.pem -outform der -out /path/to/private.der
- Convert .der to .base64
openssl base64 -in /path/to/private.der -out /path/to/Desktop/private.txt
In private.txt, you have a base64 encoded private key that you can finally use to sign your JWT. You can then call the Google API with a 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 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"