将自己的属性添加到 firebase 中的用户对象(react,redux)
Add own properties to user object in firebase (react, redux)
我正在尝试使用 firebase、react 和 redux 构建基于角色的身份验证。
在从应用程序级别创建新用户时,是否可以通过任何方式向 firebase 用户对象添加自定义 属性(例如 'permission' 或 'role'),或者我应该以其他方式完成它?
@更新 - 问题已解决
我按照 @frank-van-puffelen 的建议,使用 自定义声明 构建了基于角色的 firebase 身份验证。共有三个角色:admin、worker 和 customer。只有管理员能够创建员工帐户,客户通过 google+.
登录
我使用 firebase 云功能创建了工作人员帐户,(因为当我尝试在本地执行此操作时,我自动使用新创建的帐户登录),然后设置包含用户角色的自定义声明。 Cloud Function 还在解码一个 令牌 ,其中包含自定义声明。
这是我的代码片段:
云函数
const functions = require('firebase-functions');
const cors = require('cors');
const corsHandler = cors({origin: true});
const admin = require('firebase-admin');
admin.initializeApp();
exports.createWorkerAccount = functions.https.onRequest((request, response) => {
corsHandler(request, response, () => {
response.status(200).send('Hello from Cloud Function');
});
admin.auth().createUser({
email: request.body.email,
password: request.body.password
}).then(() => {
admin.auth().getUserByEmail(request.body.email).then((user) => {
admin.auth().setCustomUserClaims(user.uid, {role: 'worker'});
});
});
});
exports.getToken = functions.https.onRequest((request, response) => {
const token = admin.auth().verifyIdToken(request.body.token) //decoding token that contains custom claims
.then((t) => {
corsHandler(request, response, () => {
response.status(200).send(t.role); //sending role as a response
});
});
});
这两个函数都是由简单的 ajax 请求调用的。
用户的角色作为请求响应返回,然后它被推送到 redux 状态 所以我可以从应用程序的任何地方访问它。
为了将登录用户重定向到特定路径并对其进行限制,我正在使用 react-router public 和私有路径以及 firebase 函数 onAuthStateChanged。
正在检测 firebase 身份验证状态更改 - 它正在根据自定义声明将用户重定向到特定路径。
firebase.auth().onAuthStateChanged((user) => {
if (user) {
store.dispatch(login(user.uid));
firebase.auth().currentUser.getIdToken() //getting current user's token
.then((t) => {
getTokenRequest(t) // Promise containing the reqest
.then((role) => {
store.dispatch(permissions(role)); //dispatching role to store
renderApp();
if (role == "admin") {
console.log('admin');
history.push('/admin/dashboard'); //redirecting to user-role-specific path
}
else if (role == "worker") {
history.push('/worker/dashboard');
}
else {
history.push('/customer/dashboard');
}
});
});
} else {
store.dispatch(logout());
renderApp();
history.push('/');
}
});
React-router public路由组件不允许用户访问错误的路径。
export const PublicRoute = ({
isAuthenticated,
role,
component: Component,
...rest
}) => (
<Route {...rest} component={(props) => {
if(isAuthenticated && role == "admin") {
return <Redirect to="/admin/dashboard" />
} else if (isAuthenticated && role == "") {
return <Redirect to ="/customer/dashboard" />
}
else {
return <Component {...props} />
}
}} />
);
const mapStateToProps = (state) => ({
isAuthenticated: !!state.auth.uid,
role: state.role
});
export default connect(mapStateToProps)(PublicRoute);
不可以,您不能将任何个人资料信息附加到用户对象。 Firebase 用户对象中显然为此目的而存在的字段用于社交身份验证(例如,使用 Facebook 登录,Google+ ...)。
如果您需要添加自己的应用特定字段,则需要将它们添加到他们的数据库解决方案之一(例如 Firestore)。
流程示例如下:
- 使用 firebase SDK 创建用户。
- 创建用户后,您可以
得到
新创建的用户的 ID。推送一个包含用户的新 JSON
使用以下路径访问数据库的配置文件:users/${userId}
如果您使用这种模式,您将始终能够从数据库中提取相关的用户配置文件(与用户具有相同的 ID),而实际上不需要 link 它与用户帐户任何方式。
我正在尝试使用 firebase、react 和 redux 构建基于角色的身份验证。 在从应用程序级别创建新用户时,是否可以通过任何方式向 firebase 用户对象添加自定义 属性(例如 'permission' 或 'role'),或者我应该以其他方式完成它?
@更新 - 问题已解决 我按照 @frank-van-puffelen 的建议,使用 自定义声明 构建了基于角色的 firebase 身份验证。共有三个角色:admin、worker 和 customer。只有管理员能够创建员工帐户,客户通过 google+.
登录我使用 firebase 云功能创建了工作人员帐户,(因为当我尝试在本地执行此操作时,我自动使用新创建的帐户登录),然后设置包含用户角色的自定义声明。 Cloud Function 还在解码一个 令牌 ,其中包含自定义声明。
这是我的代码片段:
云函数
const functions = require('firebase-functions');
const cors = require('cors');
const corsHandler = cors({origin: true});
const admin = require('firebase-admin');
admin.initializeApp();
exports.createWorkerAccount = functions.https.onRequest((request, response) => {
corsHandler(request, response, () => {
response.status(200).send('Hello from Cloud Function');
});
admin.auth().createUser({
email: request.body.email,
password: request.body.password
}).then(() => {
admin.auth().getUserByEmail(request.body.email).then((user) => {
admin.auth().setCustomUserClaims(user.uid, {role: 'worker'});
});
});
});
exports.getToken = functions.https.onRequest((request, response) => {
const token = admin.auth().verifyIdToken(request.body.token) //decoding token that contains custom claims
.then((t) => {
corsHandler(request, response, () => {
response.status(200).send(t.role); //sending role as a response
});
});
});
这两个函数都是由简单的 ajax 请求调用的。
用户的角色作为请求响应返回,然后它被推送到 redux 状态 所以我可以从应用程序的任何地方访问它。
为了将登录用户重定向到特定路径并对其进行限制,我正在使用 react-router public 和私有路径以及 firebase 函数 onAuthStateChanged。
正在检测 firebase 身份验证状态更改 - 它正在根据自定义声明将用户重定向到特定路径。
firebase.auth().onAuthStateChanged((user) => {
if (user) {
store.dispatch(login(user.uid));
firebase.auth().currentUser.getIdToken() //getting current user's token
.then((t) => {
getTokenRequest(t) // Promise containing the reqest
.then((role) => {
store.dispatch(permissions(role)); //dispatching role to store
renderApp();
if (role == "admin") {
console.log('admin');
history.push('/admin/dashboard'); //redirecting to user-role-specific path
}
else if (role == "worker") {
history.push('/worker/dashboard');
}
else {
history.push('/customer/dashboard');
}
});
});
} else {
store.dispatch(logout());
renderApp();
history.push('/');
}
});
React-router public路由组件不允许用户访问错误的路径。
export const PublicRoute = ({
isAuthenticated,
role,
component: Component,
...rest
}) => (
<Route {...rest} component={(props) => {
if(isAuthenticated && role == "admin") {
return <Redirect to="/admin/dashboard" />
} else if (isAuthenticated && role == "") {
return <Redirect to ="/customer/dashboard" />
}
else {
return <Component {...props} />
}
}} />
);
const mapStateToProps = (state) => ({
isAuthenticated: !!state.auth.uid,
role: state.role
});
export default connect(mapStateToProps)(PublicRoute);
不可以,您不能将任何个人资料信息附加到用户对象。 Firebase 用户对象中显然为此目的而存在的字段用于社交身份验证(例如,使用 Facebook 登录,Google+ ...)。
如果您需要添加自己的应用特定字段,则需要将它们添加到他们的数据库解决方案之一(例如 Firestore)。
流程示例如下:
- 使用 firebase SDK 创建用户。
- 创建用户后,您可以 得到 新创建的用户的 ID。推送一个包含用户的新 JSON 使用以下路径访问数据库的配置文件:users/${userId}
如果您使用这种模式,您将始终能够从数据库中提取相关的用户配置文件(与用户具有相同的 ID),而实际上不需要 link 它与用户帐户任何方式。