I'm making a golang backend for a web app and an android app. I use Firebase for authentication. If I understand well,:
- I should be able to authenticate in the web app
- Get a jwt token from google
- Use this jwt in
authorization: Bearer <jwt>
for making call to my api - Validate the jwt using firebase-admin-sdk
Can someone correct me if I'm wrong ?
I use this html test page to test my authent and log the token:
<html>
<head>
<meta charset="UTF-8">
<title>Sample FirebaseUI App</title>
<script src="https://cdn.firebase.com/libs/firebaseui/2.5.1/firebaseui.js"></script>
<link type="text/css" rel="stylesheet" href="https://cdn.firebase.com/libs/firebaseui/2.5.1/firebaseui.css" />
<script src="https://www.gstatic.com/firebasejs/4.9.1/firebase.js"></script>
<script>
var config = {
apiKey: "foo",
authDomain: "bar.firebaseapp.com",
databaseURL: "fizz.firebaseio.com",
projectId: "buzz-193910",
storageBucket: "john.appspot.com",
messagingSenderId: "doe"
};
firebase.initializeApp(config);
// Initialize the FirebaseUI Widget using Firebase.
var ui = new firebaseui.auth.AuthUI(firebase.auth());
var uiConfig = {
callbacks: {
signInSuccess: function(currentUser, credential, redirectUrl) {
// User successfully signed in.
// Return type determines whether we continue the redirect automatically
// or whether we leave that to developer to handle.
console.log(credential)
return true;
},
uiShown: function() {
// The widget is rendered.
// Hide the loader.
document.getElementById('loader').style.display = 'none';
}
},
// Will use popup for IDP Providers sign-in flow instead of the default, redirect.
signInFlow: 'popup',
signInSuccessUrl: '/test-auth-on-success',
signInOptions: [
// Leave the lines as is for the providers you want to offer your users.
firebase.auth.GoogleAuthProvider.PROVIDER_ID,
firebase.auth.FacebookAuthProvider.PROVIDER_ID,
firebase.auth.TwitterAuthProvider.PROVIDER_ID,
firebase.auth.GithubAuthProvider.PROVIDER_ID,
firebase.auth.EmailAuthProvider.PROVIDER_ID,
firebase.auth.PhoneAuthProvider.PROVIDER_ID
],
// Terms of service url.
tosUrl: '<your-tos-url>'
};
ui.start('#firebaseui-auth-container', uiConfig);
</script>
</head>
<body>
<h1>Welcome to My Awesome App</h1>
<div id="firebaseui-auth-container"></div>
<div id="loader">Loading...</div>
</body>
</html>
And this is the go middleware I use to validate the token:
func (f *Authenticator) Firebase(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
authorizationHeader := req.Header.Get("authorization")
if authorizationHeader == "" {
HttpError(w, NewError("invalid authorization token"), http.StatusBadRequest)
return
}
bearerToken := strings.Split(authorizationHeader, " ")
if len(bearerToken) != 2 {
HttpError(w, NewError("invalid authorization token"), http.StatusBadRequest)
return
}
token, err := f.FirebaseClient.VerifyIDToken(bearerToken[1])
if err != nil {
HttpError(w, NewError(fmt.Sprintf("invalid authorization token: %s", err.Error())), http.StatusBadRequest)
return
}
[some custom stuff here]
req = req.WithContext(context.WithValue(context.Background(), "decoded", firebaseUser.CustomClaims))
next.ServeHTTP(w, req)
})
}
However, when I call my API with the jwt I ctrl-c/ctrl-v from the web log, I get the following error: failed to verify token signature
I don't understand why. Any ideas ?
[EDIT] I moved forward, but still not reached the end. I think some people may find this topic useful so I continue to inform community of my progress.
After a while, I found another snippet to log the api key, I changed the signInSuccess
callback to:
signInSuccess: function(currentUser, credential, redirectUrl) {
firebase.auth().currentUser.getIdToken(/* forceRefresh */ true).then(function(idToken) {
console.log(idToken)
// Send token to your backend via HTTPS
// ...
}).catch(function(error) {
console.log(error)
});
},
Which log the right token. I'm not a front end guy, I don't understand why I can get several distincts jwt, but here it is, it works. Now I get the following error: ID token issued at future timestamp: 1518108929