fireauth
fireauth copied to clipboard
Support Firebase 3 Authentication
When attempting an auth from a generated token by fire auth I am getting: FIRAuthErrorDomain Code=17000 "The custom token format is incorrect. Please check the documentation."
http://stackoverflow.com/questions/37408684/is-it-still-possible-to-do-server-side-verification-of-tokens-in-firebase-3?noredirect=1#comment62518682_37408684
does fireauth not support firebase 3?
It looks like it's not supported. I will not be able to get to this for a couple of hours but it will be top of my todo list.
In the meantime, if you know what the issue is and/or would like to open a PR I can review it and merge it quicker.
looks like the library needs to be changed to support a private key from a Firebase spawned service JSON file
https://firebase.google.com/docs/auth/server#use_a_jwt_library
Then the fireauth library could use that private key, mint a JWT token and then I can send to my client (iOS in this case)
I tried this:
...
now := time.Now().Unix()
jwtToken := jwt.NewWithClaims(jwt.SigningMethodRS256, jwt.MapClaims{
"iss": serviceAccountEmail,
"sub": serviceAccountEmail,
"aud": "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
"iat": now,
"exp": now + (60 * 60), // Maximum expiration time is one hour
"uid": u.UID,
/*
"claims" : array(
"premium_account" : true
)*/
})
// Sign and get the complete encoded token as a string using the secret
token, err = jwtToken.SignedString(privateKey)
fmt.Println(token, err)
...
Im using the jwt-go library
but I get 'key invalid' when I send in my privateKey that I received when I got a service account key from google developer portal.
https://godoc.org/github.com/dgrijalva/jwt-go#example-New--Hmac
I'm in the firebase-community slack if you want to have a bit more of a back and forth on it. I'm looking at the examples you posted now.
I used the snippet that you gave and got a different error
2016/06/27 14:33:11 test did not pass {
"error" : "Missing claim 'kid' in auth header."
}
exit status 1
What I did have to do was format and replaced the \n
with actual spaces. Something like
secret := []byte(`-----BEGIN PRIVATE KEY-----
helloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworld
helloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworld
helloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworld
-----END PRIVATE KEY-----
`)
I got it to work!
signKey, err := jwt.ParseRSAPrivateKeyFromPEM(privateKey)
if err != nil {
log.Print(err)
}
token, err = jwtToken.SignedString(signKey)
had to make sure that the key I got from google services was then parsed into the interface that jwt-go wanted then I got back a signed string that works with my iOS auth call.
Also found a similar issue on a ruby client as well https://github.com/CodementorIO/rest-firebase/issues/12
@zabawaba99 I didnt need to include the 'kid' in my code. Though I did comment out the claims array in the payload I handed to jwt.NewWithClaims(jwt.SigningMethodRS256, jwt.MapClaims{
@theprojectabot Was the kid
part of the auth header or the MapClaims
?
I'm having trouble replicating what @theprojectabot did. Here is my current code:
jwtToken := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"uid": "1",
})
signKey, err := jwt.ParseRSAPrivateKeyFromPEM([]byte(`I don't know what to put here, I tried a number of things including randomly generated private RSA keys`))
if err != nil {
log.Fatal(err)
}
token, err := jwtToken.SignedString(signKey)
if err != nil {
log.Fatal(err)
}
tmpl, err := template.ParseFiles("index.html")
if err != nil {
log.Fatal(err)
}
if err := tmpl.Execute(w, token); err != nil {
log.Fatal(err)
}
I recive the error message
Invalid Key: Key must be PEM encoded PKCS1 or PKCS8 private key
when trying to run this code.
I am trying to authenticate Steam OAuth with Firebase but the internet has absolutely nothing for it.
@Acidic9 following the instructions here on how to generate a private key for your application. You will be prompted to download a JSON file as your final step. This JSON file contains the private key you would put jwt.ParseRSAPrivateKeyFromPEM([]byte('here'))
I downloaded the JSON file, extracted the PrivateKey but when trying to use it with jwt.ParseRSAPrivateKeyFromPEM([]byte(privateKey))
It outputs 'key is invalid'.
I tried using strings.Replace(fbInfo.PrivateKey, `\n`, ` `, -1) as the private key (replacing \n with spaces) but it still output's the same error.
Here is the code I am trying to run:
package main
import (
"encoding/json"
"fmt"
"github.com/dgrijalva/jwt-go"
"io/ioutil"
"log"
"strings"
)
type firebaseInfo struct {
AuthProviderX509CertURL string `json:"auth_provider_x509_cert_url"`
AuthURI string `json:"auth_uri"`
ClientEmail string `json:"client_email"`
ClientID string `json:"client_id"`
ClientX509CertURL string `json:"client_x509_cert_url"`
PrivateKey string `json:"private_key"`
PrivateKeyID string `json:"private_key_id"`
ProjectID string `json:"project_id"`
TokenURI string `json:"token_uri"`
Type string `json:"type"`
}
func main() {
// Read Firebase json file.
fbInfoContent, err := ioutil.ReadFile("firebase-json.json")
if err != nil {
log.Fatal(err)
}
// Unmarshal json into fbInfo.
var fbInfo firebaseInfo
if err = json.Unmarshal(fbInfoContent, &fbInfo); err != nil {
log.Fatal(err)
}
// Format privateKey.
privateKey := strings.Replace(fbInfo.PrivateKey, `\n`, ` `, -1)
// Create jwtToken with SigningMethodHS256.
jwtToken := jwt.New(jwt.SigningMethodHS256)
// Create signKey by parsing RSA private key.
signKey, err := jwt.ParseRSAPrivateKeyFromPEM([]byte(privateKey))
if err != nil {
log.Fatal(err)
}
// Generate token with signKey.
token, err := jwtToken.SignedString(signKey)
if err != nil {
log.Fatal(err)
}
// Finally, after 100000 google searches my problem may be solved.
// Thank you heaps for helping me! :)
fmt.Println("SUCCESS:", token)
}
Output: key is invalid
@Acidic9 try this
package main
import (
"encoding/json"
"fmt"
"github.com/dgrijalva/jwt-go"
"io/ioutil"
"log"
"time"
)
type firebaseInfo struct {
AuthProviderX509CertURL string `json:"auth_provider_x509_cert_url"`
AuthURI string `json:"auth_uri"`
ClientEmail string `json:"client_email"`
ClientID string `json:"client_id"`
ClientX509CertURL string `json:"client_x509_cert_url"`
PrivateKey string `json:"private_key"`
PrivateKeyID string `json:"private_key_id"`
ProjectID string `json:"project_id"`
TokenURI string `json:"token_uri"`
Type string `json:"type"`
}
func main() {
// Read Firebase json file.
fbInfoContent, err := ioutil.ReadFile("firebase-json.json")
if err != nil {
log.Fatal(err)
}
// Unmarshal json into fbInfo.
var fbInfo firebaseInfo
if err = json.Unmarshal(fbInfoContent, &fbInfo); err != nil {
log.Fatal(err)
}
// Create jwtToken with SigningMethodHS256.
now := time.Now().Unix()
jwtToken := jwt.NewWithClaims(jwt.SigningMethodRS256, jwt.MapClaims{
"iss": fbInfo.ClientEmail,
"sub": fbInfo.ClientEmail,
"aud": "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
"iat": now,
"exp": now + (60 * 60), // Maximum expiration time is one hour
"uid": "Some identifier for the user",
})
// Create signKey by parsing RSA private key.
signKey, err := jwt.ParseRSAPrivateKeyFromPEM([]byte(fbInfo.PrivateKey))
if err != nil {
log.Fatal("error parsing rsa", err)
}
// Generate token with signKey.
token, err := jwtToken.SignedString(signKey)
if err != nil {
log.Fatal("error signing string", err)
}
// Finally, after 100000 google searches my problem may be solved.
// Thank you heaps for helping me! :)
fmt.Println("SUCCESS:", token)
}
I was able to get the snippet above working. A few notes:
- A private key needs the new lines. By removing them, the key is invalid.
- There are specific claims you need to pass into your token in order to create a valid one. Without it Firebase will accept your token.
Thank you so so much man, seriously, I was trying to find a solution for so long and finally it works. I really appreciate you fixing it up for me!