Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the token from firebase_auth

I'd like to get the auth token from firebase (email and password auth) to authenticate in my firebase cloud function. It seems like the functions getIdToken() and getToken() are both not working for firebase_auth package.

is there an other function or is there even a better idea to make sure only authenticated users can trigger the cloud functions?

var token = await FirebaseAuth.instance.currentUser.getIdToken();
var response = await httpClient.get(url,headers: {'Authorization':"Bearer $token"});
like image 982
Neli Avatar asked Feb 03 '23 18:02

Neli


1 Answers

I agree with @Doug on this one - callable wraps this for you and will be easier -, but my use case required me to make HTTPS calls (onRequest in Functions). Also, I think you're just in the correct path - but you're possibly not checking it in your Cloud Functions.

In your app, you'll call:

_httpsCall() async {
  // Fetch the currentUser, and then get its id token 
  final user = await FirebaseAuth.instance.currentUser();
  final idToken = await user.getIdToken();
  final token = idToken.token;

  // Create authorization header
  final header = { "authorization": 'Bearer $token' };

  get("http://YOUR_PROJECT_BASE_URL/httpsFunction", headers: header)
  .then((response) {
    final status = response.statusCode;
    print('STATUS CODE: $status');
  })
  .catchError((e) {
    print(e);
  });
}

In your function, you'll check for the token:

export const httpsFunction = functions.https.onRequest((request, response) => {
  const authorization = request.header("authorization")

  if (authorization) {
    const idToken = authorization.split('Bearer ')[1]
    if (!idToken) {
      response.status(400).send({ response: "Unauthenticated request!" })
      return
    }

    return admin.auth().verifyIdToken(idToken)
    .then(decodedToken => {
      // You can check for your custom claims here as well
      response.status(200).send({ response: "Authenticated request!" })
    })
    .catch(err => {
      response.status(400).send({ response: "Unauthenticated request!" })
    })
  }

  response.status(400).send({ response: "Unauthenticated request!" })
})

Keep in mind:

If I'm not mistaken, those tokens are valid for 1 hour, if you are going to store them somewhere, just be aware of this. I've tested locally and it takes around 200~500ms - every time - to get only the id token, which in most cases are not that big of overhead - but is significant.

like image 98
Guilherme Matuella Avatar answered Feb 08 '23 16:02

Guilherme Matuella