api - 用于登录到我的 api 的 Firebase token

标签 api firebase go firebase-authentication jwt

我正在为网络应用程序和安卓应用程序制作一个 golang 后端。 我使用 Firebase 进行身份验证。 如果我理解得很好,:

  1. 我应该能够在网络应用程序中进行身份验证
  2. 从谷歌获取一个 jwt token
  3. authorization: Bearer <jwt> 中使用此 jwt调用我的 api
  4. 使用 firebase-admin-sdk 验证 jwt

如果我错了,有人可以纠正我吗?

我使用这个 html 测试页面来测试我的身份验证并记录 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>

这是我用来验证 token 的 go 中间件:

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

但是,当我使用 Web 日志中的 jwt I ctrl-c/ctrl-v 调用我的 API 时,出现以下错误:failed to verify token signature 我不明白为什么。有什么想法吗?

[编辑] 我继续前进,但仍未到达终点。我想有些人可能会发现这个主题很有用,所以我会继续向社区通报我的进展。

过了一会儿,我找到了另一个记录 api key 的片段,我更改了 signInSuccess回调到:

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

},

哪个记录正确的 token 。我不是前端人员,我不明白为什么我可以得到几个不同的 jwt,但在这里,它有效。现在我收到以下错误:ID token issued at future timestamp: 1518108929

最佳答案

好的,我成功了。

错误一:验证 token 签名失败

所以,回顾一下:我的 html 测试页面没有记录正确的标记。好的代码如下:

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

},

错误 2:ID token 在未来时间戳发出

我的电脑时钟与世界时间不太同步。这是愚蠢的。

关于api - 用于登录到我的 api 的 Firebase token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48688503/

相关文章:

Firebase远程配置REST授权错误

go - git2go Patch() 仅返回第一个文件的差异

php - Microsoft Dynamics crm api-在账户下创建联系人

api - 在 Windows 7 手机上访问短信和通话记录

firebase - Firebase中基于多个where子句的查询

json - 在 Golang 中反序列化模式字段

http - Golang文件上传: close connection if file is too large

api - YouTube Data API v3-错误500获取播放列表列表

database - 通过 API 或网页公开数据库自动递增的 ID

swift - Collection View 的 reloadData() 不起作用