我在我的网站上使用firebase进行身份验证,我想让用户在各子域之间保持身份验证会话。
不幸的是,firebase使用本地存储来存储用户的会话。遗憾的是,每个子域都是独立的。
我已经知道你可以从服务器端使用firebase生成一个JWT令牌,但是它不允许用户注销该站点,因为用户仍然会最终登录到其他子域。
答案 0 :(得分:3)
这是正确的。 Firebase仅支持单个主机源会话。 Firebase Auth正在研究支持cookie。目前还没有简单的解决方案。请随时在Firebase论坛中请求此功能:https://groups.google.com/forum/#!forum/firebase-talk
目前,如果你真的需要这个,这里有一个相对简单的选择: 创建一个带有Firebase ID令牌的端点,并基本上为其底层用户返回一个自定义令牌(您需要使用Admin SDK执行此操作,然后验证ID令牌,获取用户UID,然后制作自定义令牌)。用户登录的子域将ID标记传递给用户仍未进行身份验证的其他子域(您可以使用iframe跨源postMessage传递它,或者只将该ID令牌保存在* .domain.com策略中) 。然后,可以使用自定义令牌将signInWithCustomToken与自定义令牌一起使用,从而有效地在此页面上登录同一用户。
这是有风险的,因为端点可能会暴露漏洞(它将短期令牌转换为无限期令牌)。如果ID令牌泄露,攻击者基本上可以在用户利用此端点时登录。
答案 1 :(得分:3)
iframe不再适用于Safari,因为它不再让iframe的原始页面访问自己的indexeddb。这意味着您无法获取ID令牌,onAuthStateChanged
将始终返回null
。
我们已经实施了另一种解决方案,我们将自定义令牌与重定向信息一起存储到安全Cookie中,将用户重定向到其他域,使用Cookie登录或注销用户,删除Cookie并重定向他再次到了存储在cookie中的位置。
再次适用于iOS和Desktop Safari。但它只有在同一个域上才有效,这样两个子域都可以访问该cookie。
答案 2 :(得分:0)
花费了更多时间之后,我打算跨子域进行单点登录,I wrote up a blog post详细说明了如何实现此目的。
我们在不同的域中拥有三个应用程序。
accounts.domain.com
app1.domain.com
app2.domain.com
我们有三个Firebase功能
...cloudfunctions.net/users-signin
...cloudfunctions.net/users-checkAuthStatus
...cloudfunctions.net/users-signout
要登录:
accounts.domain.com
应用/users-signin
云功能,该功能验证该信息,并在有效时设置一个签名的__session
cookie,其中包含用户的UID并将成功指示返回给客户端。 / li>
/users-checkAuthStatus
云函数,该函数查找已签名的__session
cookie,提取用户UID,然后使用UID和firebase-admin SDK来创建自定义身份验证令牌它返回给客户端。app1.domain.com
,该应用首先检查该人是否已经使用firebase javascript SDK登录。
/users-checkAuthStatus
云函数,该函数查找签名的__session
cookie,并在适当的情况下将自定义身份验证令牌返回给客户端。然后,客户端使用自定义身份验证令牌(如果存在)对用户进行签名。同样,这是一个高级概述,它忽略了跨站点脚本攻击,实际注销等问题。有关更多信息,请check out the blog post。
答案 3 :(得分:0)
我使用NGINX加载了要共享相同Firebase身份验证的不同Web应用程序 如果域或子域相同,则可以在Firebase中直接使用。
server {
root /var/lib/jenkins/workspace/app/dist;
index index.html index.htm index.nginx-debian.html;
server_name app.com; # example
location /app1 {
alias /var/lib/jenkins/workspace/app1/dist;
try_files $uri $uri/ =404;
}
location /app2 {
alias /var/lib/jenkins/workspace/app2;
try_files $uri $uri/ =404;
}
location /static {
alias /var/lib/jenkins/workspace/build/static;
try_files $uri $uri/ =404;
}
location ~ /\.ht {
deny all;
}
listen 80;
listen [::]:80;
}