doubianyan9749 2018-02-08 15:01
浏览 223

Firebase令牌登录到我的API

I'm making a golang backend for a web app and an android app. I use Firebase for authentication. If I understand well,:

  1. I should be able to authenticate in the web app
  2. Get a jwt token from google
  3. Use this jwt in authorization: Bearer <jwt> for making call to my api
  4. 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

  • 写回答

1条回答 默认 最新

  • douhang1913 2018-02-08 17:12
    关注

    Ok, I succeed.

    Error 1: Failed to verify token signature

    So, to recap: my html test page didn't log the right token. The good code is the following:

    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)
        });
    
    },
    

    Error 2: ID token issued at future timestamp

    My computer clock was not well synchronized with the mondial time. This is stupid.

    评论

报告相同问题?

悬赏问题

  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?