lambrohan / strapi-firebase-auth

Learn how to implement firebase authentication into strapi.
33 stars 5 forks source link

Session cookies #1

Closed MrTheFirst closed 3 years ago

MrTheFirst commented 3 years ago

@lambrohan thank you very much for the work done! But with this solution, the authorization token lives for only 1 hour. Could you help implement authorization session cookies? https://firebase.google.com/docs/auth/admin/manage-cookies#node.js

lambrohan commented 3 years ago

The easiest & recommended solution would be to generate a new idToken when your client application starts or resumes.

If you still want to go with session cookies then I think following steps would do the job

  1. Create a custom route as mentioned here and use the controller method for that route to generate a session cookie using strapi.firebase.auth().createSessionCookie(idToken, { expiresIn }).
  2. You can either verify the cookie in permissions.js following same approach as used to verify idToken or inside the controller you want to auth guard.
MrTheFirst commented 3 years ago

Thanks! I testing this solution: replace your code

try {
        const idToken = ctx.request.header.authorization.split(" ")[1];
        const decodedToken = await strapi.firebase
          .auth()
          .verifyIdToken(idToken);
        ctx.state.user = { ...decodedToken };

        if (decodedToken.strapi_uid) {
          ctx.state.user.id = decodedToken.strapi_uid;
        }

        return await next();
      } catch (error) {
        return handleErrors(ctx, err, "unauthorized");
      }

for this:

try {
        const idToken = ctx.request.header.authorization.split(' ')[1];
        const expiresIn = 60 * 60 * 24 * 14 * 1000;
        let cookie = ctx.cookies.get("session") || '';

        if (!cookie) {
          await strapi.firebase
            .auth()
            .createSessionCookie(idToken, { expiresIn })
            .then(
              (sessionCookie) => {
                cookie = sessionCookie
                // Set cookie policy for session cookie.
                const options = { maxAge: expiresIn, httpOnly: true, secure: false, domain: 'localhost' };
                ctx.cookies.set('session', cookie, options);
              });
        }
        const decodedClaims = await strapi.firebase
          .auth()
          .verifySessionCookie(cookie, true /** checkRevoked */)

        ctx.state.user = { ...decodedClaims };
        if (decodedClaims.strapi_uid) {
          ctx.state.user.id = decodedClaims.strapi_uid;
        }

        return await next();
      } catch (err) {
        return handleErrors(ctx, err, "unauthorized");
      }

Without new routes, but save Authorization header for all requests

lambrohan commented 3 years ago

Yes! That should work fine!