如何使用Firebase refreshToken重新进行身份验证?

时间:2016-07-06 20:59:30

标签: firebase firebase-authentication

我使用JS库调用firebase.auth().signInWithEmailAndPassword(email, password)并获取一个User对象。 User对象包含refreshToken

我使用curl 'https://docs-examples.firebaseio.com/rest/saving-data/auth-example.json?auth=TOKEN'拨打Firebase电话。

令牌最终会过期。为了使应用程序(iOSmacOS)具有持久登录,我想刷新令牌,如何使用REST或{{ 1}}库?我无法在文档中找到任何允许我使用JS来获取新refreshToken的电话。

4 个答案:

答案 0 :(得分:22)

当您从浏览器拨打电话.getIdToken(true)时,会自动刷新您的令牌。像这样打电话:

firebase.auth().currentUser.getIdToken(/ forceRefresh / true)
.then(function(idToken) {

}).catch(function(error) {

});

此处有更多信息https://firebase.google.com/docs/reference/js/firebase.User#getIdToken

答案 1 :(得分:18)

目前,我发现这样做的唯一方法是: https://developers.google.com/identity/toolkit/reference/securetoken/rest/v1/token

您必须发出HTTP请求:

POST https://securetoken.googleapis.com/v1/token?key=YOUR_KEY

Google developers console > API Manager > Credentials中可以找到YOUR_KEY的位置。它位于API Keys部分。

确保请求正文按以下格式构建:

grant_type=refresh_token&refresh_token=REFRESH_TOKEN

REFRESH_TOKEN是Firebase用户对象登录时的刷新令牌。

您必须设置标题Content-Type: application/x-www-form-urlencoded,否则您将收到错误(例如“MISSING_GRANT_TYPE”)。

POST来电将返回新的access_token

** 更新 **现在,Exchange a refresh token for an ID token部分下的Firebase REST文档中也记录了这一点:

https://firebase.google.com/docs/reference/rest/auth/

答案 2 :(得分:0)

// Create a callback which logs the current auth state
function authDataCallback(authData) {
  if (authData) {
    console.log("User " + authData['uid'] + " is logged with token" + authData['ie']);
  } else {
    console.log("User is logged out");
  }
}
// Register the callback to be fired every time auth state changes
var ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com");
ref.onAuth(authDataCallback);

在页面刷新时将调用事件onAuth,如果用户已注销,则authData将为空,否则为空。您可以在authdata['ie']中找到令牌。在下面的屏幕截图中,我在auth和authdata对象之后打印了令牌,你如何看到authData ['ie']和令牌是相似的。

authdata.ie and token

答案 3 :(得分:0)

我想这里的大多数人都在寻找一种方法来保持身份验证,而不是在浏览器中,例如在节点后端上。事实证明,实际上有一种方法可以做到这一点:

  1. 将刷新令牌替换为访问令牌(使用Google的公共API)
  2. 将访问令牌替换为自定义令牌(使用firebase函数,请参见下文)
  3. 使用自定义令牌登录

这是代码的本质:

const requestP = require('request-promise');
const fsP = require('fs').promises;

const refreshToken = await fsP.readFile('./refresh_token.txt');
const res = await requestP.post({
  headers: {'content-type': 'application/x-www-form-urlencoded'},
  url: 'https://securetoken.googleapis.com/v1/token?key=' + firebaseConf.apiKey,
  body: 'grant_type=refresh_token&refresh_token=' + refreshToken,
  json: true
});
const customToken = await requestP.post({
  headers: {'content-type': 'application/json'},
  url: 'https://<yourFirebaseApp>.cloudfunctions.net/createCustomToken',
  body: {token: res.access_token},
  json: true
});
await firebaseApp.auth().signInWithCustomToken(customToken);

和firebase函数:

export const createCustomToken = functions.https.onRequest(async (request, response) => {
    response.set('Access-Control-Allow-Origin', '*');

    try {
        const token = JSON.parse(request.body).token;
        const decodedToken = await admin.auth().verifyIdToken(token);
        const customToken = await admin.auth().createCustomToken(decodedToken.uid);
        response.send(customToken);
    } catch(e) {
        console.log(e);
        response.sendStatus(500);
    }
});